【问题标题】:Redux reducer - does it mutate the state?Redux reducer - 它会改变状态吗?
【发布时间】:2019-03-12 07:46:19
【问题描述】:

我遇到了以下 redux reducer,虽然它工作正常,但我认为它是错误的:

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 的替代方法是什么?

【问题讨论】:

  • 请显示您的initState的结构

标签: reactjs redux react-redux


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    你正在改变这一行中的先前状态

    state.items[itemId].item = action.item;
    

    【讨论】:

      【解决方案3】:

      您可以使用 npm immer

      它是一个微型包,可让您以更方便的方式处理不可变状态。它基于copy-on-write mechanism

      【讨论】:

        【解决方案4】:

        为了保持状态的不变性,您可以这样编写MODIFY_ITEM 动作处理程序:

        case MODIFY_ITEM:
            let itemId = state.item.id;
            return {...state, items: state.items.map((item, index) => {
                return index === itemId ? action.item : item
            })}
        

        【讨论】:

        • state.items 是一个对象。
        • 你怎么知道的?根据问题,它也可以是一个对象数组。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-27
        • 2023-03-23
        • 2018-08-09
        • 2019-02-03
        • 2019-01-30
        • 2018-04-30
        • 1970-01-01
        相关资源
        最近更新 更多