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

  1. initialPresent:

    • The initial state for the present value.
    • Defaults to an empty object ({}) if not provided.
  2. state:

    • The current state (i.e., the present value).
  3. set:

    • Updates the state by adding the current present to the past and setting newPresent as the new present.
  4. undo:

    • Reverts to the previous state by moving the last past state to present and the current present to future.
  5. redo:

    • Reapplies the last undone state by moving the first future state to present and the current present to past.
  6. clear:

    • Resets the state to the initial present value and clears past and future.
  7. canUndo:

    • A boolean indicating whether an undo operation is possible (past.length > 0).
  8. canRedo:

    • A boolean indicating whether a redo operation is possible (future.length > 0).

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

  1. Initial State:

    • past: []
    • present: { count: 0 }
    • future: []
  2. After set({ count: 1 }):

    • past: [{ count: 0 }]
    • present: { count: 1 }
    • future: []
  3. After undo:

    • past: []
    • present: { count: 0 }
    • future: [{ count: 1 }]
  4. After redo:

    • past: [{ count: 0 }]
    • present: { count: 1 }
    • future: []
  5. After clear:

    • past: []
    • present: { count: 0 }
    • future: []

API Reference

Parameters

NameTypeDescriptionDefault ValueOptional
initialPresentTThe initial state for the present value. Defaults to an empty object ({}).{}Yes

Return Values

NameTypeDescription
stateTThe current state (i.e., the present value).
set(newPresent: T) => voidA function to update the state. Adds the current present to the past and sets newPresent as the new present.
undo() => voidA function to undo the last state change. Moves the last past state to present and the current present to future.
redo() => voidA function to redo the last undone state change. Moves the first future state to present and the current present to past.
clear() => voidA function to reset the state to the initial present value and clear past and future.
canUndobooleanIndicates whether an undo operation is possible (past.length > 0).
canRedobooleanIndicates whether a redo operation is possible (future.length > 0).