这两个状态更新在反应之间有什么区别?

时间:2019-11-26 00:15:05

标签: javascript reactjs

我正在研究React课程,当时讲师正在解释有关更新状态的信息,但我无法理解这两个摘要在内部的真正区别,请参见下面的代码笔链接:

Updates the state directly snippet

class Counters extends Component {
  state = {
    counters: [
      { id: 1, value: 4 },
      { id: 2, value: 0 },
      { id: 3, value: 0 },
      { id: 4, value: 0 }
    ]
  };

  handleIncrement = counter => {
    const updatedCounters = [...this.state.counters];
    updatedCounters[0].value++;
  };
}

Updates the state indirectly then save snippet

class Counters extends Component {
  state = {
    counters: [
      { id: 1, value: 4 },
      { id: 2, value: 0 },
      { id: 3, value: 0 },
      { id: 4, value: 0 }
    ]
  };

  handleIncrement = counter => {
    const updatedCounters = [...this.state.counters];
    const index = updatedCounters.indexOf(counter);
    updatedCounters[index] = {...counter};
    updatedCounters[index].value++;
    this.setState({ counters: updatedCounters });
  };
}

在本讲座中,讲师解释说第一个代码片段确实会直接更新状态。 所以我的问题是,如果第一个示例(如讲师所述)直接更新状态,阻止第二个代码段直接更新状态的唯一事情就是下面的代码行:

updatedCounters[index] = {...counter};

如果是这样,它是如何工作的?

3 个答案:

答案 0 :(得分:2)

在第一个示例中,updatedCountersthis.state.counters的副本,但是副本中的 inside 项目是对原始对象的完全相同的引用。这可能类似于将一些书移到新盒子中。容器已更改,但内容没有更改。在第二个示例中,您不更改所选计数器,而是先复制计数器,然后再更改该副本。

答案 1 :(得分:1)

当涉及到React中的状态修改时,您始终需要记住状态不能被突变的事实。好吧,从技术上讲,您可以做到这一点,但这是不好的做法,而且是一种反模式。您始终想复制状态并修改副本,而不是原始状态对象。为什么呢它确实提高了应用程序的性能,这就是React的巨大优势。它称为immutability。 您可能还会问..“这种方法如何提高性能?” 好吧,基本上,由于具有不变性模式,react不必检查整个状态对象。取而代之的是,React进行简单的参考比较。如果旧状态未引用相同的obj。在内存中->我们知道状态已经改变。 始终尝试使用.setState()来避免以错误的方式更改状态,这就是您在此处所做的:

handleIncrement = counter => {
    const updatedCounters = [...this.state.counters];
    updatedCounters[0].value++;
  };

答案 2 :(得分:0)

基本上,我自己的问题的答案是,如果不调用setState,react不会触发必要的例程来更新屏幕上的Component“ view”值(提及第一个示例)