JSON.parse(JSON.stringify(state))是否保证还没有redux状态的变异?

时间:2017-05-06 09:25:22

标签: javascript json reactjs redux state

我一直在追踪一个redux商店正确更新的问题,但该组件并未反映出这一变化。我已经尝试了多种方法来确保我不会改变状态,但问题仍然存在。我的减速器通常采用以下形式:

case 'ADD_OBJECT_TO_OBJECT_OF_OBJECTS': {
    newState = copyState(state);
    newState.objectOfObjects[action.id] = action.obj;
    return newState;
}

对于我的copyState函数,我通常使用嵌套的Object.assign()调用,但避免错误并不是那么简单。为了测试,为了确保我没有改变状态,使用

是正确的
const copyState = (state) => {
    return JSON.parse(JSON.stringify(state));
};

作为一种保证不变异(redux)状态的方法,无论过程有多贵?

如果没有,是否还有其他可以依赖的深层复制方法,以确保我不会改变状态?

编辑: 考虑到其他人可能遇到同样的问题,我会将解决方案转发给我遇到的问题。

我试图发送一个动作,然后在后面的行中,我试图访问上一行中更新的商店中的数据。

dispatchAction(data) // let's say this updates a part of the redux state called 'collection'
console.log(this.props.collection) // This will not be updated!

请参阅https://github.com/reactjs/redux/issues/1543

2 个答案:

答案 0 :(得分:1)

是的,这是一个深刻的克隆,无论它有多贵。困难(正如问题评论中所暗示的那样)是确保state在其他地方保持不受影响。

由于您要求采用其他方法,并且不适合评论,我建议您查看ImmutableJS,这样可以消除跟踪状态变异错误的问题(但可能会有自己的问题)限制):

const { Map } = require('immutable')
const map1 = Map({ a: 1, b: 2, c: 3 })
const map2 = map1.set('b', 50)
map1.get('b') // 2
map2.get('b') // 50

答案 1 :(得分:0)

您的copyState()函数不会改变您的状态。没事。对于其他阅读此问题的人,直接走也可以

const newState = JSON.parse(JSON.stringify(oldState));

获取深层副本。感觉不干净,但这是可以的。

未看到订阅运行的原因可能是Redux在复制新状态之前将新状态(reducer函数的输出)与现有状态进行了比较。如果没有差异,则不会触发任何订阅。因此,我们从不直接更改状态而返回副本的原因-如果我们更改了状态,则永远不会检测到更改。

另一个原因可能是我们不知道您的代码中究竟有什么dispatchAction()。如果它是异步的(也许是由于中间件?),直到下一行的console.log()之后之后,更改才会应用。