【发布时间】:2021-07-10 13:27:39
【问题描述】:
return state 和 return { ...state } 在 redux reducer 默认情况下返回状态有什么区别?
【问题讨论】:
标签: javascript reactjs redux react-redux reducers
return state 和 return { ...state } 在 redux reducer 默认情况下返回状态有什么区别?
【问题讨论】:
标签: javascript reactjs redux react-redux reducers
与 React 一样,Redux 使用不变性来有效地检查更新的对象引用以获取更新的状态,这就是为什么您永远不应该直接修改/改变状态的原因。在大多数 reducer 的默认情况下,没有任何操作修改状态,因此您可以返回原始状态对象 (return state),这是安全的,因为它不会被修改。
但是,return { ...state } 将返回相同的状态,但具有不同的顶级对象引用,这将导致对更改的状态进行不必要的检查。如果您根本不修改状态,则应始终返回原始对象 (return state)。
编辑:在后续问题上添加 - 如果您 return { ...state } Redux 会将更新的状态广播到连接到存储的所有 React 组件(无论是通过钩子还是连接函数),然后 React 将进入它的生命周期更新。 React 实际上非常高效,它使用记忆和其他方法来阻止任何昂贵的重新渲染或重新绘制/重新生成 DOM,因此两者在流程方面的差异几乎没有,这只是不必要的。我认为它甚至不会像 useEffect 那样重新运行钩子,它会在到达那里之前看到冗余,或者至少使用 memoize 缓存而不重新计算
【讨论】:
return {...state} 对重新渲染没有任何影响?只有做出反应才会不必要地进行数据检查?如果我将这个减速器状态作为 useEffect 中的依赖项,我将不再进行重新渲染?
当您使用return state 时,您正在返回变量,这很糟糕,因为如果该变量发生变化,返回中传递的值也会发生变化(这被称为副作用)。
另一方面,如果您使用return { ... state },则返回的是当时变量值的副本
【讨论】:
ES6 为 javascript 中的对象文字添加了扩展属性。带有对象的扩展运算符
(…)用于创建 具有新值或更新值的现有对象或复制 具有更多属性的对象。
让我们举个例子,说明如何在对象上使用扩展运算符,
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)
mergedUsers 是user1 和user2 的副本。实际上,对象上的每个可枚举属性都将被复制到mergedUsers 对象。扩展运算符只是 Object.assign() 方法的简写,但它们是两者之间的一些区别。
如需了解更多信息,请访问Redux | Using Object Spread Operator
【讨论】:
它们在设置默认状态时都是一样的。 return { ...state } 将在您实际更改状态时有意义
return {
...state,
valueA: "a"
}
这将使用具有更新属性 valueA 的新对象更新整个状态,并将所有其他对象保留为现有值。
【讨论】:
{...state} 更改了引用,这对state 以外的重新渲染有影响吗?