扩展运算符与 JSON.parse(JSON.stringify(...)) 对于不可变对象

Spread operator vs JSON.parse(JSON.stringify(...)) for immutable objects

我正在使用 Redux,最近 运行 遇到了一个问题,我正在向数组添加消息,而 Redux 状态没有在 React 上发出重新渲染。为此,我正在使用 react-redux 库。这是我遇到的问题的示例:

// State structure
structure: { messages: {}, groups: {} }

// ---
newState = { ...prevState };
newState.messages[action.message.group] = action.message;
return newState; 

这是在更新状态,但是它没有触发对反应组件的更新,但是用 newState = JSON.parse(JSON.stringify(prevState)) 替换 newState = { ...prevState } 解决了这个问题。

谁能详细解释一下为什么会这样?我的印象是传播运算符创建了对象的克隆,直到现在我才遇到任何问题。

react-redux 连接组件进行浅层严格相等性检查以决定它们是否要更新。见 http://redux.js.org/docs/faq/ImmutableData.html

展开运算符类似于Object.assign,不会深度克隆对象。 JSON 起作用的原因是因为您创建了一个全新的对象,它可以通过严格的相等性检查,但是您的所有组件都会不必要地更新,因为现在没有任何东西可以通过严格的相等性检查。

Object.assign({}, ...prevState, ...newState) 会创建一个新的顶级对象,但不会为嵌套在 prevState 或 newState 中的任何对象创建新对象。但是,您必须小心更新嵌套对象以避免不必要的重新渲染。对于深度嵌套的对象和数组,这可能会变得棘手。

我建议检查用于管理状态的无缝不可变或不可变包。此外,reselect 库可以帮助您提取特定于组件需求的记忆对象。


2020 年 8 月 16 日更新

immer 库是当今最好的状态管理库之一