Redux reducer - 它会改变状态吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redux reducer - 它会改变状态吗?相关的知识,希望对你有一定的参考价值。
我遇到了以下redux减速机,虽然它工作正常,但我认为这是错误的:
export default (state = initState, action) => {
switch (action.type) {
case RESET_SCREEN:
return Object.assign({}, state, initState);
case MODIFY_ITEM:
let itemId = state.item.id;
state.items[itemId].item = action.item;
return Object.assign({}, state, {items: state.items});
}
}
RESET_SCREEN是否正确是正确的,因为它不会改变状态,但MODIFY_ITEM部分是坏的,因为它会发生变异?它会在哪些情况下受伤? (因为应用程序当前正在按预期运行)
MODIFY_ITEM的替代方案是什么?
答案
RESET_SCREEN是否正确是正确的,因为它不会改变状态
是的,这是对的。
但是MODIFY_ITEM部分很糟糕,因为它会发生变异
不,MODIFY_ITEM
不改变状态:
这一行:state.items[itemId].item = action.item;
变异对象(不是状态),但redux
并不关心局部对象变异 - 它甚至都不知道。
只要您返回一个新引用 - 该对象的新副本,redux
认为它是一个有效的新状态。
所以,按照redux, 这是状态突变:
case MODIFY_ITEM:
let itemId = state.item.id;
state.items[itemId].item = action.item;
return state; // <-- because you are returning the same reference. BAD
这不是状态变异:
case MODIFY_ITEM:
let itemId = state.item.id;
state.items[itemId].item = action.item;
return Object.assign({}, state, {items: state.items}); // <- A new Object. GOOD
您可能想要了解浅层检查和状态突变here。
另一答案
您正在改变此行中的先前状态
state.items[itemId].item = action.item;
另一答案
你可以使用npm immer。
它是一个小包,允许您以更方便的方式使用不可变状态。它基于copy-on-write mechanism。
另一答案
为了保持状态的不变性,你可以像这样编写MODIFY_ITEM
动作处理程序:
case MODIFY_ITEM:
let itemId = state.item.id;
return {...state, items: state.items.map((item, index) => {
return index === itemId ? action.item : item
})}
以上是关于Redux reducer - 它会改变状态吗?的主要内容,如果未能解决你的问题,请参考以下文章