State Machines
Setup
In XState version 5, you can now use the setup({ ... }) function to setup types and sources for your machines. This has many benefits:
- Reduced boilerplate for strongly typing and providing named sources
- More robust machine logic, as named sources are guaranteed to exist
- Better type inference for actions, actors, guards, delays, context, events, etc.
- Strongly-typed snapshot and done events for actors
- Strongly-typed state values
- Reusability of source logic
Example usage:
import { setup, assign } from 'xstate';
const machine = setup({
types: {
context: {} as { count: number },
events: {} as { type: 'inc' } | { type: 'dec' },
},
actions: {
increment: assign({
count: ({ context }) => context.count + 1,
}),
decrement: assign({
count: ({ context }) => context.count - 1,
}),
},
}).createMachine({
context: { count: 0 },
on: {
inc: { actions: 'increment' },
dec: { actions: 'decrement' },
},
});Ensure you are using the latest version of TypeScript (version 5.0 or higher). See the docs on TypeScript usage with XState for more information.
Setting up types
Machine types should be setup in the types property of setup({ types }). This is where you can setup the types for your machine, including:
- Types for
context - Types for
events, including event payloads - Types for
input - Types for
actions, including actionparams - Types for
guards, including guardparams - Types for
actors
Migrating from createMachine
Migrating from bare createMachine({ ... }) to setup({ ... }).createMachine({ ... }) to create a machine is simple.
- Import
setupinstead ofcreateMachinefrom'xstate' - Move
typesfromcreateMachine(...)tosetup(...) - Move action, actor, guard, etc. sources from the 2nd argument of
createMachine(config, sources)tosetup({ ... })
import {
// createMachine
setup
} from 'xstate';
const machine =
setup({
types: { ... },
actions: { ... },
guards: { ... }
})
.createMachine({
// types: { ... }
}, /* { actions, guards, ... } */);