React Native使用Redux Toolkit触发Immer producer报错是什么原因?
错误触发原因
Redux Toolkit的reducer内部默认集成了Immer库处理不可变数据更新,Immer严格要求生产者函数只能二选一执行以下操作:
- 直接修改Immer传入的draft state对象,不需要手动返回新的state
- 完全返回一个全新的state对象,不修改任何draft state的属性
你提供的代码同时触发了两种操作:
- 遍历过程中直接修改了
subItem.IsSelected属性,属于直接修改Immer的draft state - 函数最后又手动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
相关产品推荐
相关产品推荐

