JSON.parse(JSON.stringify(state)) 是否保证 redux 状态不发生变化?
Does JSON.parse(JSON.stringify(state)) guarantee no mutation of 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!
是的,这是一个深度克隆,不管它有多贵。困难(如问题下的评论中所暗示)是确保 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
您的 copyState() 函数不会改变您的状态。没事。而其他看这个问题的,直接去也可以
const newState = JSON.parse(JSON.stringify(oldState));
获取深拷贝。感觉不干净,但是可以做。
您看不到订阅的原因 运行 可能是 Redux 在复制之前将新状态(reducer 函数的输出)与现有状态进行比较。如果没有差异,它不会触发任何订阅。因此,我们从不直接改变状态而是 return 一个副本的原因——如果我们改变状态,永远不会检测到变化。
另一个原因可能是我们不知道您的代码中的 dispatchAction() 究竟做了什么。如果它是异步的(可能是因为中间件?),直到 在 下一行的 console.log() 之后才会应用更改。
我一直在追踪 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!
是的,这是一个深度克隆,不管它有多贵。困难(如问题下的评论中所暗示)是确保 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
您的 copyState() 函数不会改变您的状态。没事。而其他看这个问题的,直接去也可以
const newState = JSON.parse(JSON.stringify(oldState));
获取深拷贝。感觉不干净,但是可以做。
您看不到订阅的原因 运行 可能是 Redux 在复制之前将新状态(reducer 函数的输出)与现有状态进行比较。如果没有差异,它不会触发任何订阅。因此,我们从不直接改变状态而是 return 一个副本的原因——如果我们改变状态,永远不会检测到变化。
另一个原因可能是我们不知道您的代码中的 dispatchAction() 究竟做了什么。如果它是异步的(可能是因为中间件?),直到 在 下一行的 console.log() 之后才会应用更改。