You need to enable JavaScript to run this app. React Native使用Redux Toolkit触发Immer producer报错是什么原因?
优惠活动
大模型
产品
解决方案
定价
更多

React Native使用Redux Toolkit触发Immer producer报错是什么原因?

错误触发原因

Redux Toolkit的reducer内部默认集成了Immer库处理不可变数据更新,Immer严格要求生产者函数只能二选一执行以下操作:

  • 直接修改Immer传入的draft state对象,不需要手动返回新的state
  • 完全返回一个全新的state对象,不修改任何draft state的属性

你提供的代码同时触发了两种操作:

  1. 遍历过程中直接修改了subItem.IsSelected属性,属于直接修改Immer的draft state
  2. 函数最后又手动return了一个新的state对象,两种操作冲突就触发了Immer的报错。
解决思路

两种方案选一种即可:

方案1:使用Immer可变写法(Redux Toolkit推荐)

直接修改draft属性,不需要手动返回新对象,代码更简洁:

toggleAllClassList: (state, action) => {
    const allClassListLocal = state.classList || [];
    let isAllSelected = false;
    allClassListLocal.forEach(item => {
        item.LstParentInfo.forEach(subItem => {
            subItem.IsSelected = !subItem.IsSelected;
            isAllSelected = subItem.IsSelected;
        });
    });
    // 直接给state赋值新属性即可
    state.isClassListSelected = isAllSelected;
    state.isAllSelected = isAllSelected;
}

方案2:完全使用不可变写法,仅返回新对象

不修改任何原state的属性,逐层拷贝对象后再修改:

toggleAllClassList: (state, action) => {
    const allClassListLocal = state.classList || [];
    let isAllSelected = false;
    // 逐层拷贝修改,不触碰原state的属性
    const newClassList = allClassListLocal.map(item => {
        return {
            ...item,
            LstParentInfo: item.LstParentInfo.map(subItem => {
                const newSelected = !subItem.IsSelected;
                isAllSelected = newSelected;
                return {
                    ...subItem,
                    IsSelected: newSelected
                }
            })
        }
    });
    return {
        ...state,
        classList: newClassList,
        isClassListSelected: isAllSelected,
        isAllSelected: isAllSelected,
    };
}

内容的提问来源于stack exchange,提问作者mohsinali1317

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 20:36:04