Undo and Redo are a classic interview task, and the trick is to keep two lists. history holds every change that counts, in order. undone holds the changes you took back. Undo moves the last entry of history to the end of undone, and Redo moves the last entry of undone back to the end of history.
In this counter, the count isn't stored on its own: it is the to of the last history entry, or 0 when the history is empty. So taking an entry off the history takes the count back with it. A new change, like a click on +10, empties undone: the changes you took back no longer follow from the new count. Undo is disabled when history is empty, and Redo when undone is empty.
Three array tools do the work. Here they are on a list of letters:
const letters = ["a", "b", "c"];
letters.slice(0, -1); // ["a", "b"]: all but the last
letters[letters.length - 1]; // "c": the last one
[...letters, "d"]; // ["a", "b", "c", "d"]: a new array, one more at the end
The check clicks +10, +1 and -100, then Undo, Undo, Redo, +100, Redo and Undo. Your page must print this (shortened):
> open the page
text: Count: 0
button: Undo (disabled)
button: Redo (disabled)
numbered list (empty)
> click "+10", "+1", "-100" the count goes 10, 11, -89
> click "Undo"
screen changes:
main
- text: Count: -89
+ text: Count: 11
- button: Redo (disabled)
+ button: Redo
numbered list
- item: -100 (11 -> -89)
> click "Undo" Count: 11 -> 10, item +1 (10 -> 11) leaves
> click "Redo" Count: 10 -> 11, item +1 (10 -> 11) is back
> click "+100"
screen changes:
main
- text: Count: 11
+ text: Count: 111
- button: Redo
+ button: Redo (disabled)
numbered list
+ item: +100 (11 -> 111)
> click "Redo"
(it is disabled: nothing happens)
screen: no change
> click "Undo" Count: 111 -> 11, Redo is enabled again
Your task: in src/App.jsx, the count, the amount buttons and the history list are already there. Add the undone state, the undo and redo functions, the Undo and Redo buttons, each disabled when its list is empty, and make a new change empty undone.
Assignment
Follow the Coding Tutorial to add Undo and Redo to the counter: the undone list, the two functions, the two buttons, and the line that clears Redo after a new change.
Hint
Never change a state array in place: give setHistory and setUndone new arrays. slice(0, -1) gives all but the last entry, list[list.length - 1] is the last one, and [...list, entry] adds one at the end.
Free plan: 30 tutor messages. PRO is unlimited.
