javascript / expert
Snippet
The Command Pattern for Undo/Redo Logic
Implementing undo/redo requires managing a linear history of state snapshots. By treating every state change as a 'command' that adds to a stack, you can traverse the history using a pointer. This pattern is essential for complex editors and tools where user actions must be reversible.
snippet.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const useHistory = (initialState) => {const [state, setState] = useState(initialState);const [history, setHistory] = useState([initialState]);const [pointer, setPointer] = useState(0);const set = (next) => {const newHistory = history.slice(0, pointer + 1);newHistory.push(next);setHistory(newHistory);setPointer(newHistory.length - 1);setState(next);};const undo = () => {if (pointer > 0) {setPointer(p => p - 1);setState(history[pointer - 1]);}};return { state, set, undo };};
react
Breakdown
1
const [history, setHistory] = useState([initialState]);
The stack containing all historical versions of the state.
2
history.slice(0, pointer + 1);
Clearing future history if a new action is taken after an undo.
3
setState(history[pointer - 1]);
Moving the active state back to a previous snapshot in the history array.