【问题标题】:React's setState(), data mutation for nested structures, why not modify state directly?React setState(),嵌套结构的数据变异,为什么不直接修改状态呢?
【发布时间】:2017-03-05 22:13:23
【问题描述】:

下面的反应代码错了吗?

state={ foo: { bar: true } }  // line 1
setState(state)               // line 2   
state.foo.bar = false         // line 3
setState(state)               // line 4

如果是,为什么?

This提示错了,但没有解释为什么?

我认为没有错,原因如下:

  • line 2vdom1 已创建
  • line 4vdom2 被创建
  • 比较vdom1vdom2
  • 差异传播到实际的 DOM

如果是这种情况,那么在line3 处变异state 应该不会对line4 处发生的事情产生任何影响。

换句话说:

这应该是等效的代码:

state={ foo: { bar: true } }  // line 1
setState(state)               // line 2   
state={ foo: { bar: false } } // line 3
setState(state)               // line 4

这段代码是否等同于上面的代码?

如果没有,为什么不呢?

【问题讨论】:

标签: reactjs


【解决方案1】:

创建一个不可变的状态克隆是一个好主意,因为通过比较状态变化来优化渲染。

shouldComponentUpdate等生命周期方法中,nextProps被传入,可以与this.props进行比较。

如果您直接改变状态,那么nextProps.prop1this.props.prop1 将始终相同,因此您可能无法获得预期的行为。

我敢肯定还有其他原因,但这个原因似乎是最直接的。

【讨论】:

  • 那么如果我不使用shouldComponentUpdate那么就没有问题了?
  • 还有其他生命周期方法也可用于比较道具(如componentWillReceivePropscomponentWillUpdatecomponentDidUpdate)。并且需要注意的是,你可能不会现在使用这些,而是希望稍后在事情变得缓慢时使用。
  • 因此,如果我不使用任何生命周期方法,那很好,但是如果我想比较新旧状态/道具(任何地方),那么我不能直接改变状态。正确的 ?我的意思是,这取决于我做什么。如果我自己不比较新旧状态/道具,那很好,react 永远不会想要比较新旧状态/道具本身,对吧?因此,默认情况下,React 没有隐藏的魔法来尝试比较新旧状态。对吗?
  • 说实话,我不是 100% 确定 React 内部使用了这个。 vdom 或 diffing 算法也可以假设状态不一样。
  • 好吧,有趣!谢谢!
猜你喜欢
  • 2023-03-29
  • 2019-07-10
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
  • 2020-10-09
  • 2015-08-27
相关资源
最近更新 更多