State nodes now have a type: ...
property that defines the type of the node. There's 5 types:
type: 'parallel'
(required) for parallel state nodestype: 'history'
(required) for history state nodestype: 'final'
(required) for final state nodestype: 'compound'
(optional) for compound/nested state nodestype: 'atomic'
(optional) for atomic state nodes
Only 'parallel'
, 'history'
, and 'final'
are required for those state nodes. This replaces previous syntax:
- parallel: true,
+ type: 'parallel'
- history: true,
+ type: 'history',
+ history: 'deep', // 'shallow' by default
IDs are recommended on the root state node (machine):
const machine = createMachine({
id: 'light', // add this property!
initial: 'green',
states: {
/* ... */
}
});
This may become a strict-mode requirement in future versions.
The single nested object syntax will no longer work:
const machine = createMachine({
// ...
states: {
green: {
on: {
TIMER: {
// ⚠️ deprecated in v4
yellow: { actions: ['doSomething'] }
}
}
}
}
});
You now specify the transition as an object (or an array of objects) instead:
const machine = createMachine({
// ...
states: {
green: {
on: {
// ✅ will work in v4
TIMER: {
target: 'yellow',
actions: 'doSomething' // notice: array not necessary anymore!
}
}
}
}
});
Of course, string targets still work as expected:
const machine = createMachine({
// ...
states: {
green: {
on: {
// ✅ still works in v4
TIMER: 'yellow'
}
}
}
});
For developer convenience, every property that expects one or more entries now optionally takes an array:
{
// This still works
onEntry: ['someEntryAction'],
onExit: [{ type: 'someExitAction' }],
// But you can do this instead, if you prefer:
onEntry: 'someEntryAction',
onExit: { type: 'someExitAction' }
}
That's about it!