使用props对象初始化状态会导致变异吗?

时间:2017-11-01 05:40:56

标签: reactjs mutation

在我的React应用程序中,其中一个组件需要从props进行状态初始化。

Class ComponentA extends React.Component{
    constructor(props){
    this.state.objectA = props.objectA
    }

    someOnclickFunction(e){
      this.setState({
         objectA.value: e.target.value 
       })
    }
}

在上面的代码段中,props.objectA引用被复制到state。那么,我是通过更新状态间接地改变props吗? 或setState()函数将克隆该对象并保留objectA的新引用?

1 个答案:

答案 0 :(得分:3)

class ComponentA extends React.Component {
    constructor(props) {
        super(props);

        // state is null at this point, so you can't do the below.
        // this.state.objectA = props.objectA

        // instead, initialize the state like this:
        this.state = {
            objectA: props.objectA,
        };

    }

    someOnclickFunction(e) {
        // you can't set "objectA.value" like the following
        // this.setState({
        //     objectA.value: e.target.value
        // });

        // you need to create a new object with your property changed, like this:
        this.setState({
            objectA: Object.assign({}, this.state.objectA, { value: e.target.value }),
        })
    }
}

这是许多初学者的反应所犯的错误。您不能简单地更新对象的子属性而不会产生后果。以下也是错误的:

someOnclickFunction(e) {
    var tmp = this.state.objectA;

    // WRONG: don't do this either, you're modifying the state by doing this.
    tmp.value = e.target.value;

    this.setState({
        objectA: tmp,
    });
}

详细说明使用Object.assign执行此操作的正确方法..此函数获取所有参数并将它们合并到第一个元素中。因此,通过提供一个新对象作为第一个参数,您已使用新属性创建了第一个对象的副本。

Object.assign({}) // = {} 
Object.assign({}, objectA) // = copy of objectA
Object.assign({}, objectA, { value: "newValue" }) // = copy of objectA with 'value' = 'newValue'.