Skip to Content
⭐️ Leave a star →
HooksuseStateMachine

useStateMachine

A small finite state machine. Define a typed states → events → next state map, then call send(event) to transition. Events that aren’t valid in the current state are silently ignored — check can(event) first if you need to branch on it.

Useful for compound components that have more than two states (e.g. an async loader’s idle → loading → success | error).

import { useStateMachine } from '@wire-ui/react' type State = 'idle' | 'loading' | 'success' | 'error' type Event = 'fetch' | 'resolve' | 'reject' | 'retry' function Loader() { const { state, send, can } = useStateMachine<State, Event>( { idle: { fetch: 'loading' }, loading: { resolve: 'success', reject: 'error' }, success: { fetch: 'loading' }, error: { retry: 'loading' }, }, { initial: 'idle' }, ) return ( <div data-state={state}> <button onClick={() => send('fetch')} disabled={!can('fetch')}> Fetch </button> <button onClick={() => send('retry')} disabled={!can('retry')}> Retry </button> </div> ) }

Parameters

ParamTypeDescription
configRecord<TState, Partial<Record<TEvent, TState>>>Map of state → event → next state.
options{ initial: TState, onTransition?: (next, prev, event) => void }Initial state and optional transition listener.

Returns

KeyTypeDescription
stateTStateCurrent state.
send(event: TEvent) => voidAttempt a transition. No-op if the event isn’t valid in the current state.
can(event: TEvent) => booleanWhether the event would cause a transition.
reset() => voidReturn to the initial state.
transitionsTEvent[]Events that are valid from the current state.
Last updated on

MIT License © 2026 wire-ui

useStateMachine – Wire UI