为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕桂英4014372 2023-02-24 16:44:11
当一个组件被创建时,this.state被定义。然后,在调用 setState 之后,React 以某种方式将旧状态和新状态拆分为两个对象。例如使用钩子 shouldComponentUpdate 我们可以像这样区分这两个状态:shouldComponentUpdate(nextProps, nextState) {     return (this.state.foo != nextState.foo); }我从 github 下载了 React 源代码,我找到了调用这些函数的位置,但很快就变得很难跟踪发生了什么。我从来没有发现这种分裂(或者他们实现了这种行为)发生在哪里。我确实发现 React 曾经/可以使用浅比较来区分状态,所以我想知道他们是否只是简单地克隆状态对象,然后将更新的值合并到其中一个中,以便以后可以比较它们两个。它是否正确?在这种情况下,如何处理嵌套结构?还是他们使用某个版本的 get/set 和/或某个版本的代理 API 以某种方式捕获更改?
查看完整描述

2 回答

?
aluckdog

TA贡献1847条经验 获得超7个赞

供以后参考:我设法在 React 源代码中找到了新状态偏离旧状态的位置。

为此,我使用了 React Github 存储库的最新主分支(提交哈希e7b255341b059b4e2a109847395d0d0ba2633999 )。

免责声明,这只是我的解释,我主要是凭记忆。魔法发生在文件packages/react-reconciler/src/ReactUpdateQueue.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,它只返回以前的状态(然后根据相同的逻辑变成新状态)。

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


查看完整回答
反对 回复 2023-02-24
?
MMTTMM

TA贡献1869条经验 获得超4个赞

在使用类概念 for 的 React JS 中shouldComponentUpdate,如果我们不覆盖它,Component将始终返回 true 并PureComponent实现浅比较(浅比较通过检查两个值是否相等来工作,如果是基本类型,如字符串,数字和对象的情况它只是检查) 对道具和状态的引用,并在任何道具或状态发生变化时返回 true 。

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

  • 下一个道具将传递给组件。所以,它是新的。

  • 下一个状态在 function 上处理setState。它是从以前的状态克隆而来的,并为此添加了新的更改。因此,前一个状态的引用和下一个状态的引用总是不同的。


查看完整回答
反对 回复 2023-02-24
  • 2 回答
  • 0 关注
  • 78 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信