Check out a free preview of the full State Machines in JavaScript with XState, v2 course

The "Actions" Lesson is part of the full, State Machines in JavaScript with XState, v2 course featured in this preview video. Here's what you'd learn in this lesson:

David discusses what an action is, demonstrates entry compared to exit actions, inline compared to serialized, multiple actions, and built-in actions. A visual demonstration of how actions are expressed on a state machine path is also covered in this segment.


Transcript from the "Actions" Lesson

>> All right. Now let's talk about actions. This was also a question that was brought up like how do we express side effects inside the state machine as well. In state machine and state chart terminology in action is a side effect. It is something that is performed as the result of an event.

So there's three different types of actions that we could specify in those our entry, exit and transition actions. So, one important thing to realize is that actions don't happen randomly, they happen always due to an events. So for example, if we're in the loading when we entered the states, and I could just add this over here.

So I'm gonna make this different color, we could say entry load data actually let me make that a little bit smaller if I can [INAUDIBLE]. There we go, so what this is saying is that when we enter this date we want to start loading data and this is a side effects that happens, this side effects might eventually come back and say okay here's your data it's loaded.

And then we go into the playing states. So again, we could represent entry and exit actions here too. So we could say, play audio over here because playing the audio is a side effect. We have to tell something external that the audio file actually needs to start playing and when we're not in this playing states we want to pause the audio.

So this just make sure that the behavior of not only the way that the machine can change its behavior based on events. But also on what side effects are executed, the behavior of that is specified through these actions. Now, there are also transition actions and these are actually the actions that I would recommend you start with.

So a transition action in state machine terminology is specified with do. So it's not gonna look like this in x states. But when you're looking at state machine diagrams, it has a do in it, and that's how you know that this is a transition action. So when you're starting to specify what side effects should happen in when they should happen.

Like I said, I really recommend putting them on the transition first. So for example, when we loaded we want to start playing the audio. And when we pause, we wanna pause the audio but notice that, okay. Over here when we're paused in the play event happens, we want to play the audio as well.

So now look at these two events over here. These two events are interesting because they are doing the same thing and it's showing you that any transition that goes into the playing state needs to execute those events. And so that's how you know that that's actually a candidate for having an entry event.

[COUGH] So, use entry events when you realize that every single transition to the states results in that action being taken, same thing with exit events or sorry exit actions. If you notice that every single transition out of the states results in this exit action, then or results in this action, then you should convert that to an exit action.

So for example, if we have do pause audio but we realize that anytime that we're exiting this playing state, this pause audio happens. And so let me just make another example over here. So let's say that we're playing. And let's say that we have this dreaded, gonna color this.

We have this dreaded buffering events, which we're not gonna model in our actual state machine, but just lets pretend it happens. If we only have pause audio on this pause event, we need to duplicate it over here because we also want to pause the audio if it's buffering because obviously there's no audio to play.

And so now we know this that every single exit events, or sorry, yet every single exit transition on the state note is going to cause this same pause audio events. That's a candidate for instead having exit pause audio and removing these two. So in summary using entry and exit actions is a way to dry up your state machine logic but starts by specifying the actions on the transitions themselves first.

Alright, so the way that we specify these actions on the states or the transitions is by, here I'll add over here, is by specifying it in line at first. And so this is going to be the first thing we're doing over here. I'm going to go to the scratchpad, okay, so again we have our simple machine we have our loading machine and on success loaded let's make this a target over loaded.

So in this state objects, we could specify entry actions and we could specify multiple actions as well. So, an action can either look like a string, so we could say, load data, or it could be an object. In this way, it allows you to have parameters, just whatever you want.

But in this case, we're just gonna have it as a string just to keep things simple. All right, so now, if we go back to the homepage, we're gonna see that it shows loading over here, but I also want to log the states.actions. And so now we're going to see that we entered the loading state and now we have an array of actions.

Notice how it converted it to an object over here we have a type of load data. And that's gonna do something we haven't specified what it's going to do yet, but that shows us that this action is meant to be executed. Now, the state machine transition function will not execute actions, the interpreter will and that's one of the roles of the interpreter is not only persisting the current state, but also executing actions too.

So if instead we change this to an inline function. And we say consult.log loading data. Then you'll see here that this loading data message appears because we're entering that state and executing this action which it's going to console dot log it out. And so we could do the same thing for transitions, so I could have an action over here, actions.

And I'm just gonna do an inline action again, and say console.logdataloaded. Or I might do something like assigning data which we're gonna be doing in the future lesson. So now it says loading data. And if I send type success, that just shows you the same machine is working.

Now we see it says assigning data. And that's because it's executing that inline transition action. Now, you as a refactor target, you don't have to specify all of your actions in line. Instead what you could do is, for example, let's have load data, the machine itself has a withconfig method that allows you to specify the implementation details of these actions and other things as well.

So if I put actions as an object here, and we say, load data, And then we console.log configured loading data. Then we should see that this configured loading data message shows, and that's because it is reading from these implementation details. So those are the ways to specify actions either in Entry Exit or transition actions over here and I do recommend that you specified them as an array.

Because there is always the chance that you might need to execute multiple actions inside your transitions or in entry or exit other states.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now