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

David live codes the solution to the XState actions exercise.

Get Unlimited Access Now

Transcript from the "XState Actions Solution" Lesson

[00:00:00]
>> All right, welcome back. So let's take a look at Exercise 04. Again, what we want to do is we want every single time we have a mouse down event, we want to know exactly the position of that mouse when we clicked the, the box. So let's go ahead and do that.

[00:00:21] We're going to be adding an action to the mouse down transition. So when we're in the idle state, and mouse down happens, we want an action to happen as well. So we could say target dragging and I will add an action. So actions is plural because we could take one or more actions.

[00:00:42] In this case, we're only taking one. So context events. First, let's console the log, what exactly is in these? Just to make sure that we have some sort of action and I'm going to log Action. Cool, so when we click down, we see that we have an action.

[00:01:02] The context is undefined because we're not exactly using it yet. But we do have that mouse event. And again, we're using native mouse events. So this is really great that we could see the exact events that was passed in. Now it looks like this mouse event does have what we want.

[00:01:18] We have client x and client y, we wanna display that here somehow. So what we could do is we could say albox.dataset.points. And we're going to be using a template literal over here and just putting that in parentheses. So we're gonna have events.clientsX, and events.clientsY? So now when we click, we see that we do get that mouse position right over there.

[00:01:56] Now again, this is good for prototyping or quickly spinning up your machines, but we wants to make this in a more flexible format. So let's move all of this logic to this set points action. And so we're doing the exact same thing and instead of this action, we're going to be referencing the set points.

[00:02:22] Again, this could contain one or more actions. So it doesn't make a difference if this is an array or not. So let's make sure that it does the same thing. Indeed it does, so that's really cool. Now one other thing too, since we could customize this action, this is especially good for testing.

[00:02:48] If we want to say that this action side effect is not really going to help us out much when we're unit testing or integration testing this machine, we could say, actions. And then, we could specify that same setPoint action, remember it has to have the same name. And then, we could override this any way we want.

[00:03:11] So we could say console.log, overrided setPoint and then you'll see that it no longer shows up here. But we have this overridden however you say it setpoints over here in the console. And so when you're testing, it's a good idea to have these named to actions so that you could replace them with test implementations of your actions instead.

[00:03:41] So again, by removing that, now we have the exact same behavior that we want, which is pretty nice. And so if we were to copy this machine, so we need to copy the set points of function as well and we put it in our visualizer. Remember, it's not create machine, it's machine.

[00:04:04] And we're going to make this a string for now because we don't have an outbox on this page and we update it. We could see that we have this set point action defined over here. So we could visually verify that our logic is working exactly the same way that we expect it to.

[00:04:22] So the logic is no longer in your head, it's right there on the screen. And now we have managed side effects. So someone mentioned going points free, and what that means is you're not really taking any arguments. It's a pretty interesting way of programming popular in the functional programming world.

[00:04:39] But instead of this since we're sending the exact same events over here, we could even say service.send. It's a bit less clear what it's doing, but it is more concise arguably. And so that should give us the exact same behavior which it does, great. In the chat it was asked are there any real world use cases for entry and exit actions?

[00:05:08] And this is actually an important points, because entry and exit actions are actions where they're taken every single time you enter or exit the state respectively. But transition actions, are more explicit, because you could say that whenever you take a transition, you're going to do that action. And it doesn't depend on the state, it just depends on the transition that's taken.

[00:05:37] So one thing you could do is start off with transition actions. Once you start noticing that a lot of actions are being repeated in many transitions that either go to the same state or exit the same state, that is a sign that you could probably refactor that to be entry and exit actions instead.

[00:05:58] And so, if you want to dive more into this topic, look up the difference between more machines and mealy machines because those describe the difference between transition actions and entry and exit actions.