typescriptadvanced

useHistoryState Hook

State hook that maintains full history with undo, redo, and time-travel capabilities.

typescript
import { useState, useCallback } from 'react';

interface HistoryState<T> {
  past: T[];
  present: T;
  future: T[];
}

export function useHistoryState<T>(initialValue: T) {
  const [state, setState] = useState<HistoryState<T>>({
    past: [],
    present: initialValue,
    future: [],
  });

  const set = useCallback((newValue: T | ((prev: T) => T)) => {
    setState(s => {
      const value = typeof newValue === 'function' ? (newValue as (prev: T) => T)(s.present) : newValue;
      return { past: [...s.past, s.present], present: value, future: [] };
    });
  }, []);

  const undo = useCallback(() => {
    setState(s => {
      if (s.past.length === 0) return s;
      const prev = s.past[s.past.length - 1];
      return { past: s.past.slice(0, -1), present: prev, future: [s.present, ...s.future] };
    });
  }, []);

  const redo = useCallback(() => {
    setState(s => {
      if (s.future.length === 0) return s;
      const next = s.future[0];
      return { past: [...s.past, s.present], present: next, future: s.future.slice(1) };
    });
  }, []);

  return {
    value: state.present,
    set,
    undo,
    redo,
    canUndo: state.past.length > 0,
    canRedo: state.future.length > 0,
    history: state.past,
  };
}

Use Cases

  • Drawing apps
  • Form state undo

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.