Redux的文档中提供一个可以做undo/redo的解决办法,实际是有previous,current,prew的对象,围绕这数据的压入和弹出来实现操作步骤的记忆,结合persist就可以实现更强大的记忆功能.今天的这个增强组件实际把这个功能给包装了一下,内部实现细节仍然没有变.只需要把reducer用这个增强组件包装一下就可以用了.
redux undo/redo
提示:你可以使用redux-undo-boilerplate来开始项目.
Installation
1 | npm install --save redux-undo |
API
1 | import undoable from 'redux-undo'; |
让你的reducers变得可以重做
redux-undo
是一个reducer增强组件,它提供了undoable
函数,这个函数接收已经存在的reducer和配置对象,使用undo函数增强已经存在的reducer.
注意:如果在state.counter
之前接入,你必须要在包装reducer
之后接入state.coutner.present
.
首先导入redux-undo
1 | // Redux utility functions |
接着,添加undoable
到你的reducer
1 | combineReducers({ |
配置项
想这样传递
1 | combineReducers({ |
历史API
使用reducer包装你的reducer想这样
1 | { |
现在你可以使用state.present
获取当前的state
获取所有过去的state使用state.past
.
Undo/Redo Actions
首先导入undo/redo action creators
1 | import { ActionCreators } from 'redux-undo'; |
然后就可以使用store.dispatch()
和undo/redo action creators来执行undo/redo操作.
1 | store.dispatch(ActionCreators.undo()) // undo the last action |
配置
配置对象传递给undoable()
(值是默认值)
1 | undoable(reducer, { |
过滤Actions
如果你不想包含每一步的action,可以传递一个函数到undoable
1 | undoable(reducer, function filterActions(action, currentState, previousState) { |
或者你可以使用distinctState
,includeAction
,excludeAction
助手函数
1 | import undoable, { distinctState, includeAction, excludeAction } from 'redux-undo'; |
现在你可以使用助手函数了,相当简单
1 | undoable(reducer, { filter: includeAction(SOME_ACTION) }) |
甚至还支持数组
1 | undoable(reducer, { filter: includeAction([SOME_ACTION, SOME_OTHER_ACTION]) }) |
有什么魔法?怎么工作的
Redux文档中的实现Undo历史的方案
解释了redux-undo工作的具体细节.