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

The "Compound States" 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 hierarchical states are, initial states, selection transitions, and targeting state nodes by ID.


Transcript from the "Compound States" Lesson

>> Now we're gonna get into some of the main features of state charts. Some of them we already went over such as guarded transitions, and actions and these are things that can be applied directly to a state machine. Which we've been working with up until this point, but are also very useful in state charts.

So, what are the charts and how do they differ from state machines? State charts bring a lot of new capabilities to state machines but at the same time, they can be decomposed into state machines. State machines have this problem where when you have too many states and transitions, a lot of the connections between different states and events and things like that become redundant and also combinatorially explosive.

So let me give you a quick example, just demonstrating why that is. So if we go to xceltra, let's take this event right here, this buffering events. And let's say that we're in either a playing state or a paused state and buffering can happen. But right now it says that buffering can happen in the playing state.

But we know that, the internet connection can go out and buffering can really happen in any state. So, just gonna add another arrow here make it white and we also have buffering happening right here. We can even rotate this if we want, there we go. All right, so this is one of the first telltale signs that we're not really doing anything dry here, we're really repeating ourselves.

And we have this transition over here in this exact same transition over here, when really we want to represent that whether you're in the playing or pause state, any one of those states can receive a buffering event, and that buffering events can cause us to go back into the loading states.

Again, this isn't the actual machine that we're going to be using in our application, but it's just an example. So one thing that we could do, is instead represents the loading state in both the playing and pause state as two different states. So, if I draw like a big state over here.

Then we could group these two states together. And so let's just move this out of the way. And so now, by doing this, we could actually get rid of at least one of these transitions. And say that we want the buffering transition to go to the loading state regardless of which state we're in.

And now we could also say that, this loaded transition is going to go to this parent state, which we're gonna call ready, make that a little bit bigger. And so this ready state contains both the playing and the paused state and what we want to do is also specify that there is an initial state over here, which is this playing state.

And so now this actually allows us to dry up a lot of the logic in our application. So now instead of saying whether we're in the playing or paused state, if it's buffering go to the loading state for each of these states. Now we could say in this parents ready states when the buffering event happens, go to loading regardless of what state we're in here.

So we could add 100, 1000 trialed states here and we don't have to specify 1000 extra transitions. And so, the way that this state chart now works is when we're in the loading state and the loaded event happens, we're now in the ready states but since the ready state has trialed states it's also going to immediately enter this playing states.

So everything is still going to work just as we expect. We could pause, we could play, we could have maybe other states, but now we have some share transitions between those states. And also these transitions are going to be taken if none of the children specified that transition.

So if for some reason we have a buffering transition on one of the children, then that's going to be taken as priority over this one. It's where the same way that in events propagation in the DOM works, we start at the trialed nod. And then if that doesn't handle it, we propagate it up to the parent's node and if that doesn't handle it, we go to the next parent node and so on and so forth.

A compound state is a recursive data structure in XState. And we could specify that, I'll just go into the visualizer, so we could specify that inside any of the actual states. So, we could give this an initial of one, I'm just going to make some contrived states and then we have states one, two.

And so now if we take a look at this and there's no implementation for that guard, so I'm gonna get rid of that, we see that we immediately entered the initial state of the loaded state and we could pretty much do this as deep as we want to.

In fact I could just copy this here. And so, now we have even deeper trialed states, so just to show you over here so now we enter the initial state of loaded which I set to two and the initial state of two which I set to one. And you could go as deep as you want with this grouping the states in a way that makes sense for your application.

The general strategy for this by the way is just like you would start with transition actions and move into entry and exit actions, when you see repetition happening, you would do the same with trialed states. So if you see that playing in pause both have transitions in common, you have to stop and think to yourself, how are these states related, if they are and should they be gripped in a parent state instead.

So using compound states is more of an organizational technique which comes with a lot of cool features like we're gonna talk about in the upcoming lessons such as history states and final states. So it's definitely a really useful tool that helps you cut down on the number of transitions in your state chart

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