这个状态发生了变异吗?

时间:2018-04-01 23:10:30

标签: javascript reactjs

下面的状态是否被第二行突变?

let state = { a: 1, b: 2, c: 3 };
state = { ...state, c: 4 };

它应该制作一份状态的副本,如下所示,所以应该变异,例如。

let state = { a: 1, b: 2, c: 3 };
let old = state;

state = { ...state, c: 4 };
let newState = state;

console.log(old);
console.log(newState);

每个控制台日志的输出如下

  

{a:1,b:2,c:3}

     

{a:1,b:2,c:4}

这可以在React setState的上下文中使用吗?

3 个答案:

答案 0 :(得分:1)

如果您不清楚Javascript如何将对象视为引用,请查看here

要回答问题的第一部分,不,state没有被变异。我认为关于React你知道你不应该直接修改组件状态,例如

this.state.foo = 'bar'

因为React不会知道你已经修改过它,因此不会触发渲染周期。

应该使用组件setState方法,并且将浅合并属性,所以:

this.setState({ c: 4 })

将修改您的初始状态,以便:

{
  a: 1,
  b: 2,
  c: 4,
}

因此,在调用setState之前,您无需创建自己的状态变异副本。

答案 1 :(得分:0)

不,它没有被改变。它被重新分配为一个新对象。它创建了一个副本,引用了以前的状态。可以像concat一样考虑它。

let arr = [1,2]
arr = arr.concat([2])

这不是arr的变异。这是一个新的数组,您决定使用。

覆盖上一个变量

答案 2 :(得分:-1)

正如评论中所指出的,您的问题可能仅仅源于使用非法reserved keywordnew)。

除此之外,这里是对代码示例中操作对象引用时发生的事情的解释:

let state = { a: 1, b: 2, c: 3 };

let old = state; // the variable named "old" points (in memory)
                 // to the same reference as the variable named "state"
                 // (let's call this content "object A").
                 // If the common content they refer to is modified
                 // via the use of either variable,
                 // the same (unique) memory space is modified.

state = { ...state, c: 4 }; // Now the variable named "state"
                            // points to a new object (let's call this content "object B"),
                            // that was just created using the literal object notation. 
let newState = state; // the new variable named "newState"
                      // points to the same object as the variable
                      // named "state": "object B".

console.log(old); // displays object A
console.log(newState); // displays object B