About
Last updated
Was this helpful?
Last updated
Was this helpful?
simple undo/redo functionality for redux state containers
Protip: Check out the or the to quickly get started with redux-undo
.
Switching from 0.x to 1.0: Make sure to update your programs to the .
Help wanted: We are looking for volunteers to maintain this project, if you are interested, feel free to contact me at
This README is about the new 1.0 branch of redux-undo, if you are using or plan on using 0.6, check out
If you use Redux Undo in CommonJS environment, don’t forget to add .default
to your import.
If your environment support es modules just go by:
We are also supporting UMD build:
once again .default
is required.
redux-undo
is a reducer enhancer (higher-order reducer). It provides the undoable
function, which takes an existing reducer and a configuration object and enhances your existing reducer with undo functionality.
Note: If you were accessing state.counter
before, you have to access state.counter.present
after wrapping your reducer with undoable
.
To install, firstly import redux-undo
:
Then, add undoable
to your reducer(s) like this:
When you expose an undo redo history action to your app users, you will not want those action to apply on your whole redux state. Lets see this with naive document editor state.
wrapping the documentReducer with undoable higher order reducer
will provide only the document mountpoint of your state with an history.
an even more advanced usage would be to have many different mountpoint of your redux state, managed under redux-undo.
Don't forget to configure specific redux-undo action type for each of your mount point if you don't want to see your different history to undo/redo in sync.
Wrapping your reducer with undoable
makes the state look like this:
Now you can get your current state like this: state.present
And you can access all past states (e.g. to show a history) like this: state.past
Note: Your reducer still receives the current state, a.k.a. state.present
. Therefore, you would not have to update an existing reducer to add undo functionality.
Firstly, import the undo/redo action creators:
Then, you can use store.dispatch()
and the undo/redo action creators to perform undo/redo operations on your state:
A configuration object can be passed to undoable()
like this (values shown are default values):
You can use your redux store to set an initial history for your undoable reducers:
Or just set the current state like you're used to with Redux. Redux-undo will create the history for you:
If you want to group your actions together into single undo/redo steps, you can add a groupBy
function to undoable
. redux-undo
provides groupByActionTypes
as a basic groupBy
function:
In these cases, consecutive SOME_ACTION
actions will be considered a single step in the undo/redo history.
groupBy
FunctionIf you want to implement custom grouping behaviour, pass in your own function with the signature (action, currentState, previousHistory)
. If the return value is not null
, then the new state will be grouped by that return value. If the next state is grouped into the same group as the previous state, then the two states will be grouped together in one step.
If the return value is null
, then redux-undo
will not group the next state with the previous state.
The groupByActionTypes
function essentially returns the following:
If a grouped action type (SOME_ACTION
), the action type of the action (SOME_ACTION
).
If not a grouped action type (any other action type), null
.
When groupBy
groups a state change, the associated group
will be saved alongside past
, present
, and future
so that it may be referenced by the next state change.
After an undo/redo/jump occurs, the current group gets reset to null
so that the undo/redo history is remembered.
If you don't want to include every action in the undo/redo history, you can add a filter
function to undoable
. This is useful for, for example, excluding actions that were not triggered by the user.
redux-undo
provides you with the includeAction
and excludeAction
helpers for basic filtering. They should be imported like this:
Now you can use the helper functions:
If you want to create your own filter, pass in a function with the signature (action, currentState, previousHistory)
. For example:
You can also use our helper to combine filters.
When implementing a filter function, it only prevents the old state from being stored in the history. filter
does not prevent the present state from being updated.
It can be used like this:
MIT, see LICENSE.md
for more information.
A can be passed like this:
Note: If you want to use just the initTypes
functionality, but not import the whole redux-undo library, use !
Note: Since , only actions resulting in a new state are recorded. This means the (now deprecated) distinctState()
filter is auto-applied.
If you want to ignore an action completely, as in, not even update the present state, you can make use of .
Have a read of the in the Redux documents, which explains in detail how redux-undo works.
If you have a question or just want to discuss something with other redux-undo users/maintainers,
Also, look at the documentation over at .