Docs
useHistoryState
Add undo / redo functionality with useHistoryState.
Loading...
Installation
pnpm dlx shadcn@latest add https://usekit.kiron.dev/k/use-history-state
Usage
"use client"
import { useHistoryState } from "@/hooks/use-history-state"
export function Component() {
const { state, set, undo, redo, clear, canUndo, canRedo } = useHistoryState({
count: 0,
})
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => set({ count: state.count + 1 })}>Increment</button>
<button onClick={undo} disabled={!canUndo}>
Undo
</button>
<button onClick={redo} disabled={!canRedo}>
Redo
</button>
<button onClick={clear}>Clear</button>
</div>
)
}
Key Points
-
initialPresent
:- The initial state for the
present
value. - Defaults to an empty object (
{}
) if not provided.
- The initial state for the
-
state
:- The current state (i.e., the
present
value).
- The current state (i.e., the
-
set
:- Updates the state by adding the current
present
to thepast
and settingnewPresent
as the newpresent
.
- Updates the state by adding the current
-
undo
:- Reverts to the previous state by moving the last
past
state topresent
and the currentpresent
tofuture
.
- Reverts to the previous state by moving the last
-
redo
:- Reapplies the last undone state by moving the first
future
state topresent
and the currentpresent
topast
.
- Reapplies the last undone state by moving the first
-
clear
:- Resets the state to the initial
present
value and clearspast
andfuture
.
- Resets the state to the initial
-
canUndo
:- A boolean indicating whether an undo operation is possible (
past.length > 0
).
- A boolean indicating whether an undo operation is possible (
-
canRedo
:- A boolean indicating whether a redo operation is possible (
future.length > 0
).
- A boolean indicating whether a redo operation is possible (
Type Definitions
useHistoryState
export function useHistoryState<T extends object = object>(
initialPresent: T = {} as T
): {
state: T
set: (newPresent: T) => void
undo: () => void
redo: () => void
clear: () => void
canUndo: boolean
canRedo: boolean
}
Internal State Structure
The internal state of the hook is structured as follows:
{
past: T[]; // Array of past states
present: T; // Current state
future: T[]; // Array of future states (for redo)
}
Example Workflow
-
Initial State:
past
:[]
present
:{ count: 0 }
future
:[]
-
After
set({ count: 1 })
:past
:[{ count: 0 }]
present
:{ count: 1 }
future
:[]
-
After
undo
:past
:[]
present
:{ count: 0 }
future
:[{ count: 1 }]
-
After
redo
:past
:[{ count: 0 }]
present
:{ count: 1 }
future
:[]
-
After
clear
:past
:[]
present
:{ count: 0 }
future
:[]
API Reference
Parameters
Name | Type | Description | Default Value | Optional |
---|---|---|---|---|
initialPresent | T | The initial state for the present value. Defaults to an empty object ({} ). | {} | Yes |
Return Values
Name | Type | Description |
---|---|---|
state | T | The current state (i.e., the present value). |
set | (newPresent: T) => void | A function to update the state. Adds the current present to the past and sets newPresent as the new present . |
undo | () => void | A function to undo the last state change. Moves the last past state to present and the current present to future . |
redo | () => void | A function to redo the last undone state change. Moves the first future state to present and the current present to past . |
clear | () => void | A function to reset the state to the initial present value and clear past and future . |
canUndo | boolean | Indicates whether an undo operation is possible (past.length > 0 ). |
canRedo | boolean | Indicates whether a redo operation is possible (future.length > 0 ). |