调用setState后,React如何分离新旧状态



创建组件时,将定义该.state。然后,在调用setStateReact之后,以某种方式将旧状态和新状态拆分为两个对象。例如,使用hook shouldComponentUpdate,我们可以区分这两种状态,如下所示:

shouldComponentUpdate(nextProps, nextState) {
return (this.state.foo != nextState.foo);
}

我从github下载了React源代码,发现了这些函数的调用位置,但很快就很难跟踪发生了什么。我从未发现这种分裂(或他们如何实现这种行为(发生在哪里。我确实发现React可以使用浅层比较来区分状态,所以我想知道他们是否只是克隆状态对象,然后将更新后的值合并到其中一个中,以便以后可以比较这两个值。这是正确的吗?在这种情况下,如何处理嵌套结构?或者他们是否使用get/set版本和/或Proxyneneneba API版本以某种方式捕捉更改?

为了将来的参考:我设法在React源代码中找到了新状态与旧状态偏离的位置。

为此,我使用了React Github存储库的最新主分支(commit hashe7b255341b059b4e2a109847395d0d0ba2633999(。

免责声明,这只是我的解释,我大部分是从记忆中走出来的。魔术发生在文件packages/react reconciler/src/react UpdateQueue.new.js中,函数getStateFromUpdate。当调用setState时,会创建一个更新对象(Update.tag=UpdateState(并将其添加到更新队列中(用于异步行为(。标记用于此函数中的switch语句中的特定更新逻辑。在案例UpdateState的底部,我们看到React克隆以前的状态,并将其与";partialState";,它是传递给setState调用的状态对象。此克隆使用:

// Merge the partial state and the previous state.
return Object.assign({}, prevState, partialState);

新的状态从这个函数返回,而以前的状态仍然存储在某个地方。它们现在可以用于以后的比较。顺便说一句,ForceUpdate也在这里进行处理,它只是返回以前的状态(然后根据相同的逻辑成为新状态(。

关于我问题的第二部分,如何处理嵌套结构。考虑到这些新发现的知识,经过一番搜索,我发现了这个问题,它很好地回答了这个问题。

在使用shouldComponentUpdate的类概念的react JS中,如果我们不覆盖它,Component将始终返回true,PureComponent对props和state执行浅比较(浅比较的工作原理是在字符串、数字等基元类型的情况下检查两个值是否相等,在对象的情况下只检查引用(,如果任何props或state发生更改,则返回true。

如果我们重写shouldComponentUpdate,我们将有以前的道具和以前的状态。对象类组件中已存在存储。对于下一个道具和下一个状态,我认为:

  • 接下来的道具将传递给组件。所以,这是新的
  • 下一个状态是在函数setState上处理的。它是从以前的状态克隆出来的,并为此添加了新的更改。所以,上一个状态的引用和下一个状态引用总是不同的

最新更新