Redux Toolkit使用createSelector触发dispatch间状态突变错误求解
错误原因
- 核心问题是JavaScript的
Array.sort()方法属于原地排序方法,会直接修改调用它的原数组本身,而非返回一个新的排序后数组。 - 你在
createSelector的回调中直接对state.links(Redux store中存储的原始数组引用)调用sort,相当于在reducer之外直接修改了Redux的全局状态,违反了Redux「状态仅能在reducer中通过action触发修改」的不可变原则,因此触发了状态突变的 invariant 检查报错。 - 你提到的「在请求完成后直接在action中排序就不会报错」的原因也和这个逻辑吻合:此时你排序的是接口刚返回、还未写入store的新数组对象,修改的是临时变量而非store中的已有状态,因此不会触发突变检测。
修复方案
只需要在排序前先对原始数组做一次浅拷贝,基于拷贝后的数组排序即可,不会触碰store中的原始状态:
// links.selectors.ts 修改后代码 const selectLinksState = (state: RootState) => state.links; export const selectLinks = createSelector(selectLinksState, (state) => // 先用扩展运算符浅拷贝原数组,再对拷贝后的数组排序 [...state.links].sort((a, b) => b.clickCount - a.clickCount), );
你也可以用state.links.slice().sort(xxx)实现同样的浅拷贝效果。
内容的提问来源于stack exchange,提问作者ffx292
相关产品推荐
相关产品推荐

