【问题标题】:Uncaught TypeError: Cannot assign to read only property '' of object '#<Object>'未捕获的类型错误:无法分配给对象 '#<Object>' 的只读属性 ''
【发布时间】:2019-01-29 04:34:32
【问题描述】:

我不知道这段代码有什么不同。 a 类是组件,示例是 example.js

import React, {Component} from 'react';

const styles = {
    border: {
        display: 'inline-block',
        height: '19px',
        padding: '1px 8px 0',
        border: '2px solid',
        borderRadius: '12px',
        lineHeight: '20px',
        fontSize: '14px',
        verticalAlign: 'top',
    },
    default: {
        display: 'inline-block',
        height: '20px',
        padding: '1px 10px 0',
        borderRadius: '10px',
        lineHeight: '21px',
        fontSize: '13px',
        verticalAlign: 'top',
    },
    state: {
        display: 'inline-block',
        width: '14px',
        height: '13px',
        paddingTop: '1px',
        lineHeight: '14px',
        fontSize: '11px',
        color: '#fff',
        letterSpacing: '-0.5px',
        textAlign: 'center',
        verticalAlign: 'top',
    }
};

class A extends Component {
    static defaultProps = {
        type: 'default',
    };

    render() {
        const {
            label,
            style,
            type,
            ...other
        } = this.props;


        switch (type) {

            case 'border':
                elementStyle = styles.border;
                break;
            case 'default':
                elementStyle = styles.default;
                break;
            case 'state':
                elementStyle = styles.state;
                break;
        }

        return (
            <span style={Object.assign(elementStyle, style)} {...other}>{label}</span>
        );
    }
}

export default A;

示例代码是example.js

import A from './A';

    export default class Example extends React.Component {
        render() {
            return (
                <div>
                    <A style={{background: '#fe6969', color: '#fff'}} /> &nbsp;
                    <A style={{background: '#ff8137', color: '#fff'}} /> &nbsp;
                    <A  style={{background: '#fcb400', color: '#fff'}} /> &nbsp;
                </div>
            );
        }
    }

此代码错误是 Uncaught TypeError: Cannot assign to read only property 'background' of object '#'

我使用 babel-loader 8、babel7、webpack4

如果我正确 Object.assgin({}, elementStyle, style) 正在工作。 我认为重新渲染 A 组件时会发生此错误。 我不知道为什么会出现这个错误...

请帮助我。

【问题讨论】:

    标签: reactjs babeljs


    【解决方案1】:

    您需要做的就是使用 spread 连接/合并两个这样的对象

    {{...elementStyle, ...style}}  or
    
    {Object.assign({}, elementStyle , style) }
    

    您应该了解 Object.assign 的工作原理。它返回目标对象作为其操作的返回值。

    所以,在第一种语法中:

    Object.assign({}, elementStyle , style)
    

    您正在创建一个具有 elementStyle 和 style 可枚举属性的全新对象

    如果你这样做:

    Object.assign(elementStyle, style)
    

    那么elementStyle 本身就是目标对象,所以它会被改变,这就是Object.assign 返回的东西。

    这是我的意思的一个例子。

    示例 1:

    // With no new target object
    const original = [{id:1}, {id:2}, {id:3}];
    
    const newArray = original.map(elem => {
      return Object.assign(elem, {id:2});
    });
    
    console.log('Original object has changed');
    console.log(original);
    
    //------------------------------
    
    // With a new target object
    const original2 = [{id:1}, {id:2}, {id:3}];
    
    const newArray2 = original2.map(elem => {
      return Object.assign({}, elem, {id:2});
    });
    
    console.log('Original object has not changed');
    console.log(original2);

    示例 2:

    var styles =  {
      circle: {backgroundColor: 'yellow', height: '1005', width: '100%'},
      circleA: {backgroundColor: 'blue'},
    };
    

    所以我们需要所有的圆圈都具有默认的圆圈样式,但是我们需要更改一些属性,

    // background yellow
    <div style={styles.circle}></div>
    
    // background  blue
    <div style={Object.assign(styles.circle, styles.circleA)}></div>
    
    // expeted background yellow, but it's blue. cus styles.circle still have it's merged value
    <div style={styles.circle}></div>
    

    解决方案是将一个空对象传递给 Object.assign()。通过这样做,您是在告诉该方法使用您传递的对象生成一个新对象

    示例 3:

    const obj1 = {
      name: "J"
    }
    
    const obj2 = {
      gander: "m"
    }
    
    // Here, obj1 is the same after the Object.assign call
    console.log(Object.assign({}, obj1, obj2));
    console.log(obj1)
    console.log(obj2)
    
    console.log("without empty obj passed")
    
    // Note that after this call, obj1 holds both keys. So this will mutate it:
    console.log(Object.assign(obj1, obj2));
    console.log(obj1) // This is different now
    console.log(obj2)

    在你的情况下,

    `<A propstyle={{background: '#fe6969', color: '#fff'}} />
    
    <A propstyle={{background: '#ff8137', color: '#fff'}} /> ` 
    

    组件A在Parent中定义了两次,这意味着我们会得到两个圆,子组件会渲染两次。

    在您定义的子组件中,如下所示:

    <span style={Object.assign(elementStyle , style) }{...other}>{label}</span>
    

    第一次渲染:

    Object.assign 将属性从右到左的 props style 覆盖到 elementStyle,这里 elementStyle 本身就是目标对象,这将是 Object.assign 返回的内容。

    风格道具:{ background: "#fe6969", color: "#fff" }

    元素样式:{ background: "#fe6969", borderRadius: "10px", color: "#fff" }

    第二次渲染:

    Object.assign 尝试从右到左覆盖属性,但 elementStyle 有{ background: "#fe6969", borderRadius: "10px", color: "#fff" }

    并且 Object.assign 仍在循环中(记住示例 1 .map())

    风格道具:{ background: "#ff8137", color: "#fff" }

    抛出错误:'TypeError: Cannot assign to read only property of object' when {Object.assign(elementStyle , style) },因为没有新的目标对象。

    请找到完整代码here

    希望对您有所帮助。 read more

    【讨论】:

    • 我使用 es6 .. 我想知道为什么不能使用 Object.assgin(elementStyle, styles).. 我想知道这个原因..
    • 嗯。我明白你的答案..但我不知道为什么会出现这个错误......使用 Object.assgin(elementStyle, style) ==> 无法分配给对象'#'的只读属性'background' >
    • 谢谢你我理解上面的例子 1,2。但我不知道为什么会发生此错误...无法分配给对象'#'的只读属性'background' 为什么合并到合并对象的问题?
    • 你的意思是过去合并的span标签样式有背景,而我合并了这个有背景的span标签-->这是问题吗??
    • / 这里你看到这个打印了 5 次 check console '#ff8137', '#fcb400' 失败了这两个抛出错误,因为每次渲染你都没有创建新对象 --> 什么是新对象? ?你的意思是propstyle有问题??
    猜你喜欢
    • 2021-06-17
    • 1970-01-01
    • 2020-08-20
    • 1970-01-01
    • 2022-12-09
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    • 2019-04-27
    相关资源
    最近更新 更多