useHistoryState
State & dataA React hook for undo/redo state history with time-travel
Install
$ npm install @usefy/use-history-stateQuick start
useHistoryState.tsx
import { useHistoryState } from "@usefy/use-history-state";
function Editor() {
const { state, set, undo, redo, canUndo, canRedo } = useHistoryState(
initialCanvas,
{ limit: 50 }
);
return (
<div>
<Canvas data={state} onChange={set} />
<button onClick={undo} disabled={!canUndo}>
⟲ Undo
</button>
<button onClick={redo} disabled={!canRedo}>
⟳ Redo
</button>
</div>
);
}API reference
useHistoryState<T>(initialState, options?)
Returns the current state plus a stable set of controls for navigating and mutating the undo/redo timeline.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
initialState | T | (() => T) | — | Initial state, or a factory returning it (evaluated once on mount) |
options | UseHistoryStateOptions | {} | Configuration (see below) |
Options
| Option | Type | Default | Description |
|---|---|---|---|
limit | number | unlimited | Max entries to keep. When exceeded, oldest entries drop off the front. Values < 1 = unlimited |
Returns
| Field | Type | Description |
|---|---|---|
state | T | The current (present) state |
set | (next: T | (prev: T) => T) => void | Record a new state (value or updater). Discards any redoable "future" entries |
undo | () => void | Step back one entry. No-op when canUndo is false |
redo | () => void | Step forward one entry. No-op when canRedo is false |
goTo | (index: number) => void | Jump to an entry (index clamped to valid range) |
canUndo | boolean | Whether there is a previous state |
canRedo | boolean | Whether there is a next state |
clear | () => void | Collapse the timeline down to just the current state |
reset | () => void | Restore the initial state and wipe the timeline |
history | readonly T[] | The full timeline, oldest first |
currentIndex | number | Index of the current state within history |
Updater vs. value: like
useState, ifTis itself a function type, pass an updater (set(() => myFn)) — a bare function argument is always treated asprev => next.
Go deeper
This page is the quick reference. For every example, prop, and edge case, read the full README — or open Storybook to change props live.