解构 redux reducer 中的默认状态

Destructing default state in redux reducer

return statereturn { ...state } 之间的 redux reducer 在默认情况下返回状态有什么区别?

在设置默认状态时它们是相同的。 return { ...state } 当你真正改变状态时才有意义

return {
    ...state, 
    valueA: "a"
}

这将使用具有更新 属性 valueA 的新对象更新整个状态,并将所有其他对象保持为现有值。

ES6 has added spread property to object literals in javascript. The spread operator (…) with objects is used to create copies of existing objects with new or updated values or to make a copy of an object with more properties.

让我们来看一个如何在对象上使用展开运算符的例子,

const user1 = {
    name: 'Jen',
    age: 22
};

const clonedUser = { ...user1 };
console.log(clonedUser);

我们在这里传播 user1 对象。 user1 对象的所有键值对都被复制到 clonedUser 对象中。让我们看另一个使用扩展运算符合并两个对象的例子,

const user1 = {
    name: 'Jen',
    age: 22,
};

const user2 = {
    name: "Andrew",
    location: "Philadelphia"
};

const mergedUsers = {...user1, ...user2};
console.log(mergedUsers)

mergedUsersuser1user2 的副本。实际上,对象上的每个可枚举 属性 都将被复制到 mergedUsers 对象。传播运算符只是 Object.assign() 方法的 shorthand 但是,它们是两者之间的一些差异。

要了解更多信息,请访问 Redux | Using Object Spread Operator

与 React 一样,Redux 使用不可变性来有效地检查更新的对象引用以获取更新的状态,这就是为什么你不应该直接 modify/mutate 状态。在大多数 reducer 的默认情况下,没有任何操作修改状态,因此您可以 return 原始状态对象 (return state),这是安全的,因为它不会被修改。

但是,return { ...state } 将 return 一个相同的状态,但具有不同的顶级对象引用,这将导致对更改的状态进行不必要的检查。如果你根本不修改状态,你应该总是 return 原始对象 (return state).

编辑:添加了后续问题 - 如果你 return { ...state } Redux 将更新后的状态广播到所有连接到商店的 React 组件(通过挂钩或连接功能),然后 React 会去进入它的生活方式周期更新。 React 实际上非常高效,它使用 memoizing 和其他方法来停止任何昂贵的重新渲染或 repainting/regenerating DOM 因此两者在流程方面的差异几乎为零,这是不必要的。我不认为它甚至会像 useEffect 那样重新运行钩子,它会在到达那里之前看到冗余或者至少使用 memoize 缓存而不是重新计算

当您使用 return state 时,您正在 return 变量,这很糟糕,因为如果该变量发生变化,return 中传递的值也会发生变化(这是众所周知的作为副作用)。

另一方面,如果您使用 return { ... state },那么您 return 是当时变量值的副本