Skip to content

Instantly share code, notes, and snippets.

@freddi301
Last active October 26, 2019 17:10
Show Gist options
  • Save freddi301/e2da52f2fb4eb08597456b89b87aea92 to your computer and use it in GitHub Desktop.
Save freddi301/e2da52f2fb4eb08597456b89b87aea92 to your computer and use it in GitHub Desktop.
Undoable Reducer react hooks #react #hook
function useUndoReducer<State, Action>(
reducer: (state: State, action: Action) => State,
initial: () => State[]
) {
const [index, setIndex] = useState(0);
const [history, setHistory] = useState(initial);
const state = history[index];
const dispatch = useCallback(
(action: Action) => {
const updated = history.slice(0, index + 1);
updated.push(reducer(state, action));
setHistory(updated);
setIndex(index + 1);
},
[index, state, history]
);
const undo = useCallback(() => {
if (index > 0) {
setIndex(index - 1);
}
}, [index]);
const redo = useCallback(() => {
if (index < history.length - 1) {
setIndex(index + 1);
}
}, [index, history]);
return [state, dispatch, undo, redo, history, setIndex] as const;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment