Actions vs. actors
Sometimes it’s unclear whether you should use an action or an actor. Both appear to do similar things, executing side effects. Let’s break down the differences:
Actions are “fire-and-forget”; as soon as their execution starts, the statechart running the actions forgets about them. If you specify an action as async, the action won’t be awaited before moving to the next state. Below is an example:
const machine = createMachine(
{
context: {
userName: '',
},
initial: 'collectingFormDetails',
states: {
collectingFormDetails: {
on: {
SUBMIT: {
actions: 'submitForm',
target: 'submitted',
},
},
},
submitted: {},
},
},
{
actions: {
submitForm: async (context) => {
await createUser(context.userName);
},
},
}
);
You might think that the sequence would work as follows:
- In the
collectingFormDetailsstate, we receive theSUBMITevent. - We execute the
submitFormaction and wait for it to finish. - When the
submitFormaction is done, we go to thesubmittedstate.
Instead, the sequence works like this:
- In the
collectingFormDetailsstate, we receive theSUBMITevent. - We execute the
submitFormaction and immediately transition to thesubmittedstate. - The result of the
submitFormaction is ignored.
To handle submitForm properly, we need to use an actor:
const machine = createMachine(
{
context: {
userName: '',
},
initial: 'collectingFormDetails',
states: {
collectingFormDetails: {
on: {
SUBMIT: {
target: 'submitting',
},
},
},
submitting: {
invoke: {
src: 'submitForm',
onDone: {
target: 'submitted',
},
onError: {
target: 'errored',
},
},
},
errored: {},
submitted: {},
},
},
{
// `actors` in v5
services: {
submitForm: async (context) => {
await createUser(context.userName);
},
},
}
);
Now, the sequence in the example above is:
- In the
collectingFormDetailsstate, we receive theSUBMITevent. - We go to the
submittingstate, where we execute thesubmitFormactor. - When the
submitFormactor is done, we go to thesubmittedstate. - If the
submitFormactor errors, we go to theerroredstate.
The main difference between actions and actors is that actions can’t communicate back to the machine. Actors can.