Redux文档花了很多时间来解释我们应该如何避免在reducer中改变状态。
但是这些行为本身并不会自动被深度复制,对吗?
如果我们这样做:
....
switch (actions.type) {
case 'UPDATE_PROP1':
return {
...state,
prop1: actions.payload.obj1
}
....
这似乎是一个(一部分)纯函数。
但是,如果obj1
不是原始的,而是一个我们从外部保留引用的对象,我们改变了这个引用后面的对象,我们也会改变状态并得到相同的未定义行为吗?
所以这基本上是另一个我们不改变行动的契约吗?或者说,它能安全地完成吗?
1条答案
按热度按时间ymdaylpp1#
Redux文档花了很多时间来解释我们应该如何避免在reducer中改变状态。
是的,他们是这样。这是为了明确你不应该改变你的状态/动作/等等。
但是这些行为本身并不会自动被深度复制,对吗?
不,动作对象只是普通的旧JavaScript对象,具有一些必需/预期的属性,例如。
type
和payload
。它们被分派到存储中,并通过reducer树来实现对下一个状态的更新。如果我们这样做:
这似乎是一个(一部分)纯函数。
但是,如果
obj1
不是原始的,而是一个我们从外部保留引用的对象,我们改变了这个引用后面的对象,我们也会改变状态并得到相同的未定义行为吗?是的,如果你保存
actions.payload.obj1
引用到state.prop1
,然后在reducer树的其他地方改变actions.payload.obj1
值(* 例如:另一个reducer函数 *)或者甚至在UI代码中一直返回,那么state.prop1
将被“突变”。类似地,由于state.prop1
是对动作的有效负载的引用,如果你改变state.prop1
的值,它可以改变其他reducer阅读的actions.payload.obj1
的值。所以这基本上是另一个我们不改变行动的契约吗?
是的,这是另一个不改变传递对象的契约。这实际上是React中的一个硬性规则:“虽然不能改变任何东西!“.不要改变状态引用,不要改变属性。不要改变将成为状态一部分的对象引用。
或者说,它能安全地完成吗?
官方上说,不,不是真的。技术上...你可以通过创建一个新的对象引用并复制(deep copy/clone)对象属性来实现。但这不是突变。