Skip to content

Actions

Action creators for use in state machine transitions, entry, and exit handlers.

assign

Updates the machine’s context.

function assign<TContext, TEvent>(
assignment: Partial<TContext> | ((params: { context: TContext; event: TEvent }) => Partial<TContext>)
): AssignAction

Examples:

// Static assignment
assign({ count: 0 })
// Dynamic from context
assign(({ context }) => ({ count: context.count + 1 }))
// Dynamic from event
assign(({ event }) => ({ value: event.payload }))

effect

Runs an Effect for side effects.

function effect<TContext, TEvent, R, E>(
fn: (params: { context: TContext; event: TEvent }) => Effect.Effect<void, E, R>
): EffectAction

Examples:

// Simple logging
effect(() => Effect.log("State entered"))
// Using context
effect(({ context }) => Effect.log(`Count: ${context.count}`))
// Service call
effect(({ context }) =>
Effect.gen(function* () {
const api = yield* ApiService;
yield* api.saveProgress(context);
})
)

raise

Sends an event to self.

function raise<TContext, TEvent>(
event: TEvent | ((params: { context: TContext; event: TEvent }) => TEvent)
): RaiseAction

Examples:

// Static event
raise(new Done())
// Dynamic event
raise(({ context }) => new SetValue({ value: context.computed }))

emit

Emits an event to external listeners (via actor.on()).

function emit<TContext, TEvent>(
event: EmittedEvent | ((params: { context: TContext; event: TEvent }) => EmittedEvent)
): EmitAction

Examples:

// Static event
emit({ type: "notification", message: "Complete!" })
// Dynamic event
emit(({ context }) => ({ type: "progress", percent: context.progress }))

log

Shorthand for logging.

function log<TContext, TEvent>(
message: string | ((params: { context: TContext; event: TEvent }) => string)
): EffectAction

Examples:

log("Entering state")
log(({ context }) => `Count is ${context.count}`)

sendTo

Sends an event to a child actor.

function sendTo<TContext, TEvent>(
target: string | ((params: { context: TContext; event: TEvent }) => string),
event: MachineEvent | ((params: { context: TContext; event: TEvent }) => MachineEvent)
): SendToAction

Examples:

// Static target and event
sendTo("childMachine", new Start())
// Dynamic target
sendTo(({ context }) => `child-${context.activeId}`, new Ping())
// Dynamic event
sendTo("timer", ({ context }) => new SetDuration({ ms: context.timeout }))

sendParent

Sends an event to the parent actor.

function sendParent<TContext, TEvent>(
event: MachineEvent | ((params: { context: TContext; event: TEvent }) => MachineEvent)
): SendParentAction

Examples:

// Static event
sendParent(new ChildComplete())
// Dynamic event
sendParent(({ context }) => new ResultReady({ data: context.result }))

forwardTo

Forwards the current event to a child actor.

function forwardTo<TContext, TEvent>(
target: string | ((params: { context: TContext; event: TEvent }) => string)
): ForwardToAction

Examples:

// Static target
forwardTo("childMachine")
// Dynamic target
forwardTo(({ context }) => context.activeChildId)

spawnChild

Spawns a child machine actor.

function spawnChild<TContext, TEvent>(
machine: MachineDefinition,
options: {
id: string | ((params: { context: TContext; event: TEvent }) => string)
}
): SpawnChildAction

Examples:

// Static ID
spawnChild(ChildMachine, { id: "myChild" })
// Dynamic ID
spawnChild(WorkerMachine, {
id: ({ context }) => `worker-${context.workers.length}`
})

stopChild

Stops a child machine actor.

function stopChild<TContext, TEvent>(
childId: string | ((params: { context: TContext; event: TEvent }) => string)
): StopChildAction

Examples:

// Static ID
stopChild("myChild")
// Dynamic ID
stopChild(({ event }) => event.childToStop)

cancel

Cancels a pending delayed transition.

function cancel<TContext, TEvent>(
sendId: string | ((params: { context: TContext; event: TEvent }) => string)
): CancelAction

Example:

// State config with cancellable delay
{
after: {
5000: { id: "timeout", target: "timedOut" }
},
on: {
CANCEL: {
target: "cancelled",
actions: [cancel("timeout")]
}
}
}

enqueueActions

Dynamically build an action list at runtime.

function enqueueActions<TContext, TEvent, R, E>(
collect: (params: {
context: TContext;
event: TEvent;
enqueue: ActionEnqueuer<TContext, TEvent, R, E>;
}) => void
): EnqueueActionsAction

ActionEnqueuer interface:

interface ActionEnqueuer {
(action: Action): void;
assign: (assignment: Partial<TContext> | ((p) => Partial<TContext>)) => void;
raise: (event: TEvent | ((p) => TEvent)) => void;
effect: (fn: (p) => Effect) => void;
}

Example:

enqueueActions(({ context, event, enqueue }) => {
// Always do this
enqueue.assign({ lastAction: Date.now() });
// Conditional actions
if (context.count > 10) {
enqueue.assign({ status: "high" });
enqueue.effect(() => Effect.log("High count!"));
}
// Based on event
if (event.notify) {
enqueue.raise(new SendNotification());
}
})

Invoke Action Helpers

Type-safe assign helpers for invoke result handlers.

assignOnSuccess

function assignOnSuccess<TContext, TOutput>(
fn: (params: { context: TContext; output: TOutput }) => Partial<TContext>
): AssignAction

assignOnFailure

function assignOnFailure<TContext, TError>(
fn: (params: { context: TContext; error: TError }) => Partial<TContext>
): AssignAction

assignOnDefect

function assignOnDefect<TContext>(
fn: (params: { context: TContext; defect: unknown }) => Partial<TContext>
): AssignAction

Example:

invoke: invoke({
src: () => fetchUser(),
onSuccess: {
target: "ready",
actions: [
assignOnSuccess<MyContext, User>(({ output }) => ({
user: output,
loading: false,
})),
],
},
onFailure: {
target: "error",
actions: [
assignOnFailure<MyContext, ApiError>(({ error }) => ({
errorMessage: error.message,
})),
],
},
})

assignResult

A shorthand for handling all invoke outcomes in one place. Use this when you want to update context without transitioning to different states.

invoke: invoke({
src: () => Effect<TOutput, TError, R>,
assignResult: {
success: (params: { context: TContext; output: TOutput }) => Partial<TContext>;
failure?: (params: { context: TContext; error: TError }) => Partial<TContext>;
catchTags?: {
[K in TError["_tag"]]?: (params: { context: TContext; error: ErrorByTag<TError, K> }) => Partial<TContext>;
};
defect?: (params: { context: TContext; defect: unknown }) => Partial<TContext>;
}
})

Example:

invoke: invoke({
src: () => fetchWeather(),
assignResult: {
success: ({ output }) => ({
weather: { status: "loaded", data: output },
}),
failure: ({ error }) => ({
weather: { status: "error", message: error.message },
}),
defect: ({ defect }) => ({
weather: { status: "crashed", message: String(defect) },
}),
},
})

With typed error handling:

invoke: invoke({
src: () => fetchWeather(), // Effect<Weather, NetworkError | ParseError, never>
assignResult: {
success: ({ output }) => ({ weather: output }),
catchTags: {
NetworkError: ({ error }) => ({
error: `Network issue: ${error.message}`,
}),
ParseError: ({ error }) => ({
error: `Invalid data: ${error.message}`,
}),
},
failure: ({ error }) => ({ error: error.message }), // Fallback
defect: ({ defect }) => ({ error: String(defect) }),
},
})

See Also