A reusable, generic undo/redo system for React applications. Demonstrates state management best practices, type-safe hooks, and a scalable architecture for undoable actions.
- Generic, type-safe
useUndoRedohook - Maintains a history of past and future states
- Undo and redo operations with a clean API
- Decouples state management from UI logic
- Works with any type of state: objects, arrays, primitives
- Minimal, functional demo component
This pattern is suitable for real-world applications that require undoable state changes, such as editors, forms, or dashboards.
- Import the hook and provide an initial state:
const { state, setState, undo, redo, canUndo, canRedo } = useUndoRedo({
counter: 0,
});- Update state as usual:
setState({ counter: state.counter + 1 });- Undo or redo changes:
undo(); // revert to previous state
redo(); // redo last undone changecanUndoandcanRedoindicate whether undo/redo is currently possible.- History and future stacks are managed automatically.
- Directly mutating state without a history mechanism
- Implementing undo/redo logic in multiple components individually
- Leads to inconsistent behavior and hard-to-maintain code
- Centralized undo/redo logic via a generic hook
- Type-safe and generic
- Works with any React state
- Clean separation between logic and UI
- Scalable for multiple state types
src/
hooks/
useUndoRedo.ts ← core hook logic
components/
UndoRedoDemo.tsx ← demo UI to test hook
UndoRedoDemo.css ← styling
App.tsx ← integrates demo component
- Increment and decrement a counter
- Undo and redo state changes using buttons
- Buttons are disabled when undo/redo is not possible
npm install
npm run devMIT