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 - 它会改变状态吗?的主要内容,如果未能解决你的问题,请参考以下文章

React Redux Reducer 触发但不改变状态

Redux 动作/reducers 与直接设置状态

Reactjs Redux 我们应该为状态树中的每个对象创建 sub reducer 吗?

React Redux reducer 未更新状态

redux

所有的 redux 动作都应该有相应的 reducer 吗?