Redux的文档中提供一个能够作undo/redo的解决办法,实际是有previous,current,prew的对象,围绕这数据的压入和弹出来实现操做步骤的记忆,结合persist就能够实现更强大的记忆功能.今天的这个加强组件实际把这个功能给包装了一下,内部实现细节仍然没有变.只须要把reducer用这个加强组件包装一下就能够用了.html
提示:你能够使用redux-undo-boilerplate来开始项目.git
npm install --save redux-undo
复制代码
import undoable from 'redux-undo';
undoable(reducer)
undoable(reducer, config)
复制代码
redux-undo
是一个reducer加强组件,它提供了undoable
函数,这个函数接收已经存在的reducer和配置对象,使用undo函数加强已经存在的reducer.github
**注意:**若是在state.counter
以前接入,你必需要在包装reducer
以后接入state.coutner.present
.npm
首先导入redux-undo
redux
// Redux utility functions
import { combineReducers } from 'redux';
// redux-undo higher-order reducer
import undoable from 'redux-undo';
复制代码
接着,添加undoable
到你的reducer数组
combineReducers({
counter: undoable(counter)
})
复制代码
配置项
想这样传递bash
combineReducers({
counter: undoable(counter, {
limit: 10 // set a limit for the history
})
})
复制代码
使用reducer包装你的reducer想这样函数
{
past: [...pastStatesHere...],
present: {...currentStateHere...},
future: [...futureStatesHere...]
}
复制代码
如今你能够使用state.present
获取当前的state 获取全部过去的state使用state.past
.ui
首先导入undo/redo action creatorsthis
import { ActionCreators } from 'redux-undo';
复制代码
而后就能够使用store.dispatch()
和undo/redo action creators来执行undo/redo操做.
store.dispatch(ActionCreators.undo()) // undo the last action
store.dispatch(ActionCreators.redo()) // redo the last action
store.dispatch(ActionCreators.jumpToPast(index)) // jump to requested index in the past[] array
store.dispatch(ActionCreators.jumpToFuture(index)) // jump to requested index in the future[] array
复制代码
配置对象传递给undoable()
(值是默认值)
undoable(reducer, {
limit: false, // set to a number to turn on a limit for the history
filter: () => true, // see `Filtering Actions` section
undoType: ActionTypes.UNDO, // define a custom action type for this undo action
redoType: ActionTypes.REDO, // define a custom action type for this redo action
jumpToPastType: ActionTypes.JUMP_TO_PAST, // define custom action type for this jumpToPast action
jumpToFutureType: ActionTypes.JUMP_TO_FUTURE, // define custom action type for this jumpToFuture action
initialState: undefined, // initial state (e.g. for loading)
initTypes: ['@@redux/INIT', '@@INIT'] // history will be (re)set upon init action type
initialHistory: { // initial history (e.g. for loading)
past: [],
present: config.initialState,
future: []
},
debug: false, // set to `true` to turn on debugging
})
复制代码
若是你不想包含每一步的action,能够传递一个函数到undoable
undoable(reducer, function filterActions(action, currentState, previousState) {
return action.type === SOME_ACTION; // only add to history if action is SOME_ACTION只有some_action的action才能记录
})
// or you could do...
undoable(reducer, function filterState(action, currentState, previousState) {
return currentState !== previousState; // only add to history if state changed只有state变化的才能记录重作
})
复制代码
或者你能够使用distinctState
,includeAction
,excludeAction
助手函数
import undoable, { distinctState, includeAction, excludeAction } from 'redux-undo';
复制代码
如今你能够使用助手函数了,至关简单
undoable(reducer, { filter: includeAction(SOME_ACTION) })
undoable(reducer, { filter: excludeAction(SOME_ACTION) })
// or you could do...
undoable(reducer, { filter: distinctState() })
复制代码
甚至还支持数组
undoable(reducer, { filter: includeAction([SOME_ACTION, SOME_OTHER_ACTION]) })
undoable(reducer, { filter: excludeAction([SOME_ACTION, SOME_OTHER_ACTION]) })
复制代码
Redux文档中的实现Undo历史的方案
解释了redux-undo工做的具体细节.