Most apps let users make changes but never let them take them back. This challenge is about building the mechanism that changes everything: a history you can rewind.
๐งฉ Overview
Build a notes editor whose add, edit, toggle, and delete actions are tracked in a useReducer past/present/future history, so every change can be undone and redone with buttons or keyboard shortcuts.
๐ https://www.reactchallenges.com/challenges/undo-redo
โ Requirements
- The list starts with the notes "Buy groceries" and "Walk the dog".
- Each note is editable through an input.
- Each note has a done toggle and a delete button.
- Undo and redo are disabled on first render.
- Adding a note appends it to the list and clears the new-note field.
- A change enables undo; undoing restores the previous list, disables undo when there is nothing left to undo, and enables redo.
- Redo reapplies an undone change and disables itself once there is nothing left to redo.
- Adding, editing, toggling, and deleting a note can each be undone.
- An undone change can be redone.
- Consecutive edits to the same note collapse into a single undo step.
- An edit that does not change the text is ignored and adds no history.
- Adding an empty or whitespace-only note is ignored and adds no history.
- Undo is triggered by Cmd/Ctrl+Z.
- Redo is triggered by Shift+Ctrl+Z.
- Pressing undo with no history or redo with nothing to redo leaves the list unchanged.
- The status line reports how many undo and redo steps are available.
- New notes always get unique identifiers, even after undoing and adding again.
- Making a new change after undoing clears the redo stack.
๐ก Notes
- The history shape most people reach for is
{ past, present, future }:presentis what renders, whilepastandfutureare stacks of snapshots. - Return the same state object for a no-op (a blank note, an edit that doesn't change the text, undo/redo with an empty stack) so React bails out and history stays clean.
- Keep the id counter outside the history โ rewinding it on undo would let two different notes share an id.
๐งช Tests
- renders the initial notes
- disables undo and redo on load
- adds a note and clears the input
- enables undo after a change and disables it again after undoing
- redoes an undone change
- undoes a deletion and restores the note
- undoes a toggle and restores the previous state
- undoes an edit and restores the previous text
- collapses continuous edits to one note into a single undo step
- ignores an edit that does not change the text
- does not push history when adding an empty note
- does not push history when adding a whitespace-only note
- undoes with Ctrl+Z
- undoes with Cmd+Z
- redoes with Shift+Ctrl+Z
- does nothing when undo is pressed with no history
- does nothing when redo is pressed with no future
- reports the available undo and redo steps
- keeps note identifiers unique after undo and redo
- clears the redo stack when a new change is made
Work through it and you'll come away knowing how to model reversible state with a reducer โ a skill that shows up everywhere from text editors to form builders to drag-and-drop canvases.
Top comments (0)