0.4.0
This versions solves two issues:
- Returns
send
fromupdate
:
A Common pattern is to update the context then immediately send an event to transition as illustrated by the async example). With this PR, the following two lines:
update(context => ({ data: coffees, ...context }));
send('SUCCESS');
Can now be written as:
update(context => ({ data: coffees, ...context })).send('SUCCESS');
- Allows events to contain arbitrary payload:
Until now there was no simple way to bring outside data into the state machine context (like a form or a subscription). With this PR, events can be sent in an object notation in addition to the string notation: (e.g.send("TOGGLE")
orsend({ type: "TOGGLE" })
. The latter accepts arbitrary keys and values that can be accessed inside effects and guards.
const [machine, send] = useStateMachine<{ time: number }>({ time: 0 })({
initial: 'idle',
verbose: true,
states: {
idle: {
on: {
START: 'running',
},
effect(_, update, event) {
update(() => ({ time: event?.resetTime }));
},
},
running: {
on: {
STOP: 'idle',
},
effect(_, update) {
// ...
},
}
},
});
send({ type: 'STOP', resetTime: 10 });
By default all additional values are typed as any
, but the user can provide custom types as a generic:
const [machine, send] = useStateMachine<{ time: number }, { type: 'START' } | { type: 'STOP'; resetTime: number }>({
time: 0,
})({
initial: 'idle',
verbose: true,
states: {
idle: {
on: {
START: 'running',
},
effect(_, update, event) {
if (event?.type === 'STOP') update(() => ({ time: event?.resetTime }));
},
},
running: {
on: {
STOP: 'idle',
},
effect(_, update) {
// ...
},
},
},
});
send({ type: 'STOP', resetTime: 10 });