Implement Undo History - Tuong-Nguyen/JavaScript-Structure GitHub Wiki
Algorithm
Shape of State
{
past: Array<T>,
present: T,
future: Array<T>
}
Handling Actions
UNDO
- Remove last element from
past - Set
presentto removed element in previous step - Insert old
presentat the beginning offuture
REDO
- Remove first element from
future - Set
presentto removed element in previous step - Insert old
presentat the end ofpast
Others
- Insert
presentat the end ofpast - Set
presentto the new state after handling the action - Clear the
future
Using Redux Undo
Redux Undo is a library that provides simple Undo and Redo functionality for any part of Redux tree
Installation
npm install --save redux-undo
Usage
Wrap reducer with undoable reducer enhancer
import undoable, { distinctState } from 'redux-undo'
/* ... */
const todos = (state = [], action) => {
/* ... */
}
const undoableTodos = undoable(todos, {
filter: distinctState()
})
export default undoableTodos
distinctState(): ignore the actions that didn't result in a state change- Other configurations
combineReducers()
combineReducersnot changed but the original reducer will now refer to enhanced reducer- Note:
undoablecan wrap one or more reducers at any level.
Update the Selectors
Now state looks like
{
visibilityFilter: 'SHOW_ALL',
todos: {
past: [
[],
[{ text: 'Use Redux' }],
[{ text: 'Use Redux', complete: true }]
],
present: [
{ text: 'Use Redux', complete: true },
{ text: 'Implement Undo' }
],
future: [
[
{ text: 'Use Redux', complete: true },
{ text: 'Implement Undo', complete: true }
]
]
}
}
state.todos->state.todos.present
Add Actions
- Import
ActionCreatorsfromredux-undo
import { ActionCreators as UndoActionCreators } from 'redux-undo'
- Undo action creator:
UndoActionCreators.undo() - Redo action creator:
UndoActionCreators.redo()