useHistory
A hook that automatically tracks changes to an Observable and manages undo/redo history.
Records a snapshot automatically whenever the source Observable changes. Built on top of useManualHistory, with additional support for auto-commit, pause/resume, and transaction.
Every keystroke becomes an undo checkpoint. Pause tracking when you want to experiment without polluting the stack.
Every change commits immediately while tracking is active.
Newest snapshot is pinned at the top.
import { function useObservable<T>(): Observable<T | undefined> (+3 overloads)
A React hook that creates a new observable
useObservable } from "@legendapp/state/react";import { import useHistory
useHistory } from "@usels/web";
const const text$: any
text$ = useObservable<unknown>(value: Promise<unknown> | (() => unknown) | unknown, deps?: React.DependencyList): any (+3 overloads)
A React hook that creates a new observable
useObservable("hello");const { const undo: any
undo, const redo: any
redo, const canUndo$: any
canUndo$, const canRedo$: any
canRedo$ } = import useHistory
useHistory(const text$: any
text$);
const text$: any
text$.any
set("world"); // auto-committedconst undo: any
undo(); // text$ → "hello"const redo: any
redo(); // text$ → "world"pause / resume — stop and restart auto-tracking
Section titled “pause / resume — stop and restart auto-tracking”import { function useObservable<T>(): Observable<T | undefined> (+3 overloads)
A React hook that creates a new observable
useObservable } from "@legendapp/state/react";import { import useHistory
useHistory } from "@usels/web";
const const text$: any
text$ = useObservable<unknown>(value: Promise<unknown> | (() => unknown) | unknown, deps?: React.DependencyList): any (+3 overloads)
A React hook that creates a new observable
useObservable("hello");const { const pause: any
pause, const resume: any
resume, const isTracking$: any
isTracking$ } = import useHistory
useHistory(const text$: any
text$);
const pause: any
pause();const text$: any
text$.any
set("not tracked"); // skipped — no history record
const resume: any
resume();const text$: any
text$.any
set("tracked again"); // auto-committed
// Resume and immediately commit the current valueconst resume: any
resume(true);transaction — group mutations into one record
Section titled “transaction — group mutations into one record”Multiple changes inside transaction() are recorded as a single undo step.
Call the provided cancel() to abort the commit entirely.
import { function useObservable<T>(): Observable<T | undefined> (+3 overloads)
A React hook that creates a new observable
useObservable } from "@legendapp/state/react";import { import useHistory
useHistory } from "@usels/web";
const const value$: any
value$ = useObservable<unknown>(value: Promise<unknown> | (() => unknown) | unknown, deps?: React.DependencyList): any (+3 overloads)
A React hook that creates a new observable
useObservable(0);const { const transaction: any
transaction, const undo: any
undo } = import useHistory
useHistory(const value$: any
value$);
const transaction: any
transaction((cancel: any
cancel) => { const value$: any
value$.any
set(1); const value$: any
value$.any
set(2); const value$: any
value$.any
set(3); // Only one history record for the final value 3});
const undo: any
undo(); // value$ → 0 (single step back)shouldCommit — conditional auto-commit
Section titled “shouldCommit — conditional auto-commit”Return false from shouldCommit to skip recording specific values.
import { function useObservable<T>(): Observable<T | undefined> (+3 overloads)
A React hook that creates a new observable
useObservable } from "@legendapp/state/react";import { import useHistory
useHistory } from "@usels/web";
const const count$: any
count$ = useObservable<unknown>(value: Promise<unknown> | (() => unknown) | unknown, deps?: React.DependencyList): any (+3 overloads)
A React hook that creates a new observable
useObservable(0);
// Only record even numbersconst { const undo: any
undo } = import useHistory
useHistory(const count$: any
count$, { shouldCommit: (value: any) => boolean
shouldCommit: (value: any
value) => value: any
value % 2 === 0,});capacity — limit undo depth
Section titled “capacity — limit undo depth”import { function useObservable<T>(): Observable<T | undefined> (+3 overloads)
A React hook that creates a new observable
useObservable } from "@legendapp/state/react";import { import useHistory
useHistory } from "@usels/web";
const const text$: any
text$ = useObservable<unknown>(value: Promise<unknown> | (() => unknown) | unknown, deps?: React.DependencyList): any (+3 overloads)
A React hook that creates a new observable
useObservable("");
// Keep at most 50 undo stepsconst { const undo: any
undo, const redo: any
redo } = import useHistory
useHistory(const text$: any
text$, { capacity: number
capacity: 50 });dispose — permanently stop tracking
Section titled “dispose — permanently stop tracking”import { function useObservable<T>(): Observable<T | undefined> (+3 overloads)
A React hook that creates a new observable
useObservable } from "@legendapp/state/react";import { import useHistory
useHistory } from "@usels/web";
const const value$: any
value$ = useObservable<unknown>(value: Promise<unknown> | (() => unknown) | unknown, deps?: React.DependencyList): any (+3 overloads)
A React hook that creates a new observable
useObservable(0);const { const dispose: any
dispose } = import useHistory
useHistory(const value$: any
value$);
const dispose: any
dispose(); // stops auto-tracking permanently; undo/redo stacks still usableType Declarations
Section titled “Type Declarations”export interface UseHistoryOptions<Raw, Serialized = Raw> extends UseManualHistoryOptions<Raw, Serialized> { eventFilter?: EventFilter; deep?: boolean; shouldCommit?: (newValue: Raw) => boolean;}export interface UseHistoryReturn<Raw, Serialized = Raw> extends UseManualHistoryReturn<Raw, Serialized> { readonly isTracking$: ReadonlyObservable<boolean>; pause: Fn; resume: (commitCurrent?: boolean) => void; transaction: (fn: (cancel: Fn) => void) => void; dispose: Fn;}export declare function useHistory<Raw, Serialized = Raw>(source$: Observable<Raw>, options?: DeepMaybeObservable<UseHistoryOptions<Raw, Serialized>>): UseHistoryReturn<Raw, Serialized>;Source
Section titled “Source”Contributors
Section titled “Contributors”- tigerwest
Changelog
Section titled “Changelog”a7392ab2026-03-06 - feat(core,browser): add sync strategy hooks (tigerwest)