如何在RTK项目中使用redux-undo包装所有切片实现全Store撤销?
问题结论
你的现有写法完全错误,无法正常运行。
错误原因
redux-undo的undoable()是reducer增强函数,仅接受reducer函数作为入参,你代码里传入的是configureStore()生成的store实例,它本身不是reducer,不具备接收state、action返回新状态的能力,传入后会直接触发运行时报错。
正确实现方式
你需要先组合所有业务切片得到根reducer,用undoable包装整个根reducer后,再传入store配置项,参考代码如下:
import { configureStore, combineReducers } from "@reduxjs/toolkit"; import undoable from 'redux-undo' import todoSlice from "../features/todo/todoSlice"; import visibilityFilterSlice from "../features/visibilityFilter/visibilityFilterSlice"; // 组合所有切片生成根reducer const rootReducer = combineReducers({ todos: todoSlice, visibilityFilter: visibilityFilterSlice, }) // 包装根reducer,给全量状态添加撤销能力 const undoableRootReducer = undoable(rootReducer) const store = configureStore({ reducer: undoableRootReducer, }); export default store;
注意事项
- 该实现下所有触发状态变更的action都会被记录到撤销历史,调用
dispatch(undoable.ActionCreators.undo())即可一次性回退所有切片的状态,满足全局撤销的需求。 - 包装后store的state结构会变为redux-undo的标准结构:
state.past:历史状态栈,存储过去的状态快照state.present:当前实际的业务状态,你之前定义的todos、visibilityFilter都在这个字段下,组件读取状态时需要从state.present.todos、state.present.visibilityFilter取值,直接读state.todos会得到undefinedstate.future:重做状态栈,存储撤销后可恢复的状态快照
- 如果后续需要过滤不需要进入撤销栈的action,可以给
undoable传入第二个配置参数,通过filter字段自定义过滤规则即可。
内容的提问来源于stack exchange,提问作者Intaek
相关产品推荐
相关产品推荐

