【问题标题】:Is Initializing state with props object causes mutation?使用 props 对象初始化状态会导致突变吗?
【发布时间】:2018-04-13 09:59:39
【问题描述】:

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

Class ComponentA extends React.Component{

    constructor(props){
    this.state = {
      objectA: props.objectA
    }

    }

    someOnclickFunction(e){
      let updatedObjA = this.state.objectA;
       updatedObjA.value = e.target.value;
      this.setState({
         objectA: updatedObjA
       })
    }
}

在上面的代码 sn-p 中,props.objectA 引用被复制到状态。那么,我是否通过更新状态来间接改变props? 或者setState() 函数将克隆对象并为objectA 保留新的引用?

【问题讨论】:

    标签: reactjs mutation


    【解决方案1】:
    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 }),
            })
        }
    }
    

    这是许多 react 初学者都会犯的错误。您不能简单地更新对象的子属性而没有后果。以下也是错误的:

    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'.
    

    注意:Object.assign() 是浅克隆,不是深克隆。

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 1970-01-01
      • 2018-09-18
      • 1970-01-01
      • 2019-01-16
      • 1970-01-01
      • 2015-04-17
      • 1970-01-01
      • 2015-05-10
      相关资源
      最近更新 更多