不可变对象的扩展运算符与 JSON.parse(JSON.stringify(...)) [英] Spread operator vs JSON.parse(JSON.stringify(...)) for immutable objects

查看:47
本文介绍了不可变对象的扩展运算符与 JSON.parse(JSON.stringify(...))的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm working with Redux and recently ran into a problem where I was adding messages to an array and the Redux state was not issueing a re-render on React. I'm using the react-redux library for this. Here's an example of the problem I was having:

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

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

这是更新状态,但它不会触发对反应组件的更新,而是将 newState = { ...prevState } 替换为 newState = JSON.parse(JSON.stringify(prevState)) 解决了这个问题.

This was updating the state however it wasn't triggering an update to the react component, however replacing newState = { ...prevState } with newState = JSON.parse(JSON.stringify(prevState)) resolved the issue.

谁能详细解释为什么会发生这种情况?我的印象是扩展运算符创建了对象的克隆,直到现在我才遇到任何问题.

Could anyone explain why this is happening in detail? I was under the impression that the spread operator created a clone of the object and I've never had any problems with it until now.

推荐答案

react-redux 连接组件做一个浅层严格相等检查来决定它们是否要更新.参见 http://redux.js.org/docs/faq/ImmutableData.html

react-redux connected components do a shallow strict equality check to decide if they want to update. see http://redux.js.org/docs/faq/ImmutableData.html

扩展运算符类似于 Object.assign 并且不会深度克隆对象.JSON 工作的原因是因为您创建了一个全新的对象,该对象将通过严格相等检查,但是您的所有组件都将不必要地更新,因为现在没有任何内容可以通过严格相等检查.

The spread operator is like Object.assign and does not deeply clone an object. The reason the JSON thing worked is because you created a whole new object which would pass the strict equality check, however all your components would update needlessly because nothing will pass a strict equality check now.

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

Object.assign({}, ...prevState, ...newState) would create a new top-level object, but it would not create a new object for any objects nested in prevState or newState. However, you would have to carefully update nested objects so as to avoid needless re-renders. This can get tricky for deeply nested objects and arrays.

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


I'd recommend checking out the seamless-immutable or immutable packages for managing state. Also, the reselect library can help you extract memoized objects specific to your component's needs.


immer 库是目前最好的状态管理库之一

the immer library is one of the best state management libraries as of today

这篇关于不可变对象的扩展运算符与 JSON.parse(JSON.stringify(...))的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆