我正在研究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};
如果是这样,它是如何工作的?
答案 0 :(得分:2)
在第一个示例中,updatedCounters
是this.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”值(提及第一个示例)