When defining a state machine we start from states and initial state.
For a toggle machine we can define the following states:
- "On": equivalent to
true
- "Off": equivalent to
false
In this example we mark the initial state as "Off".
We add states and initial state inside createMachine
:
initial
: the initial statestates
: an object containing all the states as keys
import { setup } from "xstate";
const machine = setup({}).createMachine({
// ๐ Initial state (references a state)
initial: "Off",
// ๐ States (object)
states: {
Off: {},
On: {},
},
});
Transitions using events
A state machine can change its current state when it receives an event.
Inside setup/types
we define the events that our machine can receive:
Types for the machine are defining by using
as
for each property.This pattern allows typescript to infer the type of each machine property without defining a concrete value.
import { setup } from "xstate";
type Event = { type: "toggle" };
const machine = setup({
types: {
events: {} as Event,
},
}).createMachine({
initial: "Off",
states: {
Off: {},
On: {},
},
});
Similar as we did for events in
useReducer
, XState requires adding atype
property to each event (e.g.{ type: "toggle" }
).
Each state inside states
is an object that defines its own properties and transitions.
When the machine receives an event, a state can intercept the event and perform a state transition:
- When the state is "Off" and
toggle
is triggered then transition to "On" - When the state is "On" and
toggle
is triggered then transition to "Off"
An event is captured from a state by using on
:
import { useMachine } from "@xstate/react";
import { setup } from "xstate";
type Event = { type: "toggle" };
const machine = setup({
types: {
events: {} as Event,
},
}).createMachine({
initial: "Off",
states: {
Off: {
on: {
toggle: {
// Do something on "toggle" event
},
},
},
On: {
on: {
toggle: {
// Do something on "toggle" event
},
},
},
},
});
We specify the state transition by using target
:
import { setup } from "xstate";
type Event = { type: "toggle" };
const machine = setup({
types: {
events: {} as Event,
},
}).createMachine({
initial: "Off",
states: {
Off: {
on: {
toggle: { target: "On" }, // ๐ `Off` + `toggle` => `On`
},
},
On: {
on: {
toggle: { target: "Off" }, // ๐ `On` + `toggle` => `Off`
},
},
},
});