This library is, by far, the best option nowadays to start to working with finite state machines and statecharts in our apps. Whether or not you’ve heard the term “finite state machines,” we’ve been using them for a long time, and not only in computation—in real life too. As loggedOut state should only trigger an error action when moving from loading to loggedOut & not when moving from loggedIn to loggedOut. These concepts can be extended to the real world without having to refactor your entire application. Inspired by mood this module is using the well known finite state machine pattern to alleviate some of the issues that crop up in complex React applications by strictly separating the management of states from your components. It’s easy to get confused by thinking you must either use, say, xstate or Redux; but it’s important to note that state machines are more of an implementation concept, concerned with how you design your state — not necessarily how you manage it. This means that if our application is in the loggedOut state and we call our transition function with an action of SUBMIT, our application will always transition from the loggedOut state to the loading state. The finite state machine pattern works regardless of whether we use React, Vue or Angular. Arguments. For now, our finite state machine is doing basically nothing. If you’re interested in diving deeper into state machines, I’ve spent the last several months working on a course on finite state machines — if you sign up for the email list, you’ll receive a discount code when the course launches in August. Now enhanced with: Learn about finite state machines, the advantages of this computer science concept and how we can use it in React apps. In the constructor(), we’re declaring our default state and binding the handleInput() method so that it references the proper this internally. In a Mealy machine, the output depends on both the current state and the inputs of the system. CSS-Tricks is created by Chris and a team of swell people. You have the right to request deletion of your Personal Information at any time. Maybe it’ll take some time to grasp the concepts of this powerful library, but in the long term, it’ll help you to write better state logic. At the same time, there is a not so new method for modeling state that has existed long before react was even thought about. React An Introduction to Finite State Machines: Simplifying React State Management with State Machines As their name suggests, a finite state machine is an abstract machine that can only exist in one of any number of (finite) states at once. To change for another state, we need input. In React, context is a state held in closure to be referenced by many components via a providing and consuming component architecture. To set the stage a bit, let’s take a quick look at a CodePen demo of what we’ll be building. In this guide, we will build a Finite State Machine from scratch using XState and React # What is a Finite State Machine? # useService(service) A React hook (opens new window) that subscribes to state changes from an existing service (opens new window). In medicine, a stent is a metal or plastic tube inserted into the lumen of an anatomic vessel or duct to keep the passageway open*. We’ll use the state diagram above to guide us. What in the heck do I mean by state design? First, let’s install some packages: Now, we should import the Machine object from xstate and the useMachine hook from @xstate/react. We can see that our logic is bug-free, since we’re not able to be in more than one state at a time. State machines are an excellent refactor target — meaning, next time you’re working on a component that is littered with boolean flags like isFetching and isError, consider refactoring that component to use a state machine. A full example of the working state machine can be found in my Codepen. Looking back at that state diagram, our machine consists of those same three states: logged out, logged in, and loading. We’re going to compare each div element to each state, so we’ll only display the div of that respective element. Inside each state, we’re going to change to something like this: When we have actions to dispatch, we need to change our events to an object and have two properties: target is the next state, and actions are the actions that we’re going to dispatch. So our first button will have the name of Yellow, but it will be disabled if it doesn’t match the state of green. Working in the same file as our state machine definition, let’s create an component and set it up with everything we’ll need. We can start by building a login component for our application. Take a course from David Khorshid on building applications using the idea of state machines, which, as David Puts it, means "you will spend less time debugging edge cases and more time modeling complex application logic in a visually clear and robust way". The state can only change (transition) in response to an input. Find and fix web accessibility issues with ease using axe DevTools Pro. Each button will change the state for a specific target. Finally, our render() method displays our login form, but notice that the component is also a context consumer. @xstate/react provides an easy way to use hooks for integration with our React components. While confirming, we show the modal. Here’s the state machine we’ll be building to control a confirmation dialog. A finite state machine is a way to model state transitions in a system. After the state changes, it produces an output. State hooks - like useState or useReducer. Finite state machines might be the right choice for you right now, to solve unexpected side effects and maintain your application bug-free for a long time. Now that our state is yellow, after the timer hits 10 seconds, the state will change to red. — into our context, making it available to any of our consumer components. With the context property, we’ll be able to get our context, and the matches property is a function to check if our finite state machine is in that specific state. Or in other words it is a tool that restores blood flow through narrow or blocked arteries. Inside our Machine object, we define our state using a property called states, which is also an object. We also have four different action types that can be fired: SUBMIT, SUCCESS, FAIL, and LOGOUT. Have you heard about react-state-rxjs immutable state management library based on rxjs?. In the past, when building an application that needs to fetch some data from a backend service and display it to the user, I’ve designed my state to use boolean flags for various things like isLoading, isSuccess, isError, and so on down the line. Transition to a new state could depend on the previous state and a set of external factors. Managing State Machines With A Library. these hooks use and possibly manipulates the parent component stateful logic.. Effect hooks - one of useEffect or useLayoutEffect. The goal of every React developer when starting an application is, for sure, to create up-to-date state functions that don’t cause unexpected side effects in our application. All Rights Reserved. Copyright © 2021, Progress Software Corporation and/or its subsidiaries or affiliates. correction: State machines in action The component-driven model of most modern frameworks — React, Vue, Angular, etc — is quite favorable for using state machines. Note that the transition() function that it calls is actually the one we defined in our component, which has been passed down via props. I encourage you to explore various approaches to determine what works best for you, your team, and your application(s). React components has a built-in state object.. XState has a visualizer that helps us create our finite state machines. Blissful peace of mind. Progress is the leading provider of application development and digital experience technologies. Subscribe to be the first to get our expert-written articles and tutorials for developers! BTW. Other nice features that statecharts have are actions, guards, multiple transitions and state history. I'm having some real Baader-Meinhof lately with finite state machines. REACT HOOKS STATE STATE MACHINE Why state machines are relevant to frontend development # A finite state machine is not a new concept in the world of computing or mathematics. Well, in XState, we have something called Actions. Finally, in our render() method, we’re actually defining our provider component and then passing all of our current state through the value props, which makes the state available to all of the components beneath it in the component tree. Great job showing how to break down state, context & UI components. these hooks receive a callback function and usually a dependency array. This module stay true to the original intent behind React: Describe states as static components only (dynamic relationships within a component … First, we’re passing our current application state and the event type or action to xstate, so we can determine our next state. actions: ['error'] That’s very awesome. } The state object is where you store property values that belongs to the component.. So, we’ll create a title to display how many times our state was updated, and also create three div elements using the matches property to display content. So, for example, we want to give the name of YELLOW to our transition, and we want to go to the yellow state. If you’ve worked much with React in the past, you may be familiar with how data is passed from parent to child through props. This library is, by far, the best option nowadays to start to working with finite state machines and statecharts in our apps. Since we’re passing the logout() method to all of our consumers, we can also give the user the option of logging out from anywhere in the component tree. In a statechart, a state that has no substate is called an atomic state. A Moore machine is more deterministic but reacts slower to input changes compared to a Mealy machine. npx create-react-app react-xstate-example. Then, in nextState, we take any actions associated with that next state (which will be one of our onEntry or onExit actions) and run them through the command() method — then we take all of the results and set our new application state. But I've never seen one in production and it's starting to feel like I've been sleeping on something important. First conceptualized many decades ago, a finite state machine is a mathematical model of a machine that as the name suggests, can maintain one of a finite number of states. To break things down one more time, let’s look at the loggedOut: { on: { SUBMIT: 'loading'} } line . Context helps alleviate the pain of prop drilling by providing a way to share data between components without having to explicitly pass that data through the component tree, making it perfect for storing authentication data. If you return a function from your effect, it will be invoked when leaving that state. Using statecharts, you can have hierarchical machines and/or parallel machines — meaning individual React components can have their own internal state machine, but still be connected to the overall state of your application. Why state machines are relevant to frontend development A finite state machine is not a new concept in the world of computing or mathematics. Based on either your previous activity on our websites or our ongoing relationship, we will keep you updated on our products, solutions, services, company news and events. As this number of boolean flags grows, though, the number of possible states that my application can have grows exponentially with it — significantly increasing the likelihood of a user encountering an unintentional or error state. service - An XState service (opens new window). Start by adding the following code above the return statement in our main app function: const [state, send] = useMachine(NavMachine); const navbarClass = "navbar-menu " + (state.value === "opened" && "is-active"); We also learned how we can work with finite state machines in React apps using XState, a JavaScript/TypeScript library that allows us to create finite state machines and have a better app, creating a more consistent state and bug-free logic. Now, let’s create some components that consume our application context. We’re going to put the useMachine that we created as value, and also create a new object. Using statecharts, you can have hierarchical machines and/or parallel machines — meaning individual React components can have their own internal state machine, but still be connected to the overall state of your application. Progress collects the Personal Information set out in our Privacy Policy and Privacy Policy for California Residents and uses it for the purposes stated in that policy. ): import { createMachine } from 'xstate'; export const toggleMachine = createMachine({ id: 'toggle', initial: 'inactive', states: { inactive: { on: { … It's a really powerful package that can be used to manage state in React Apps. Leonardo is a full-stack developer, working with everything React-related, and loves to write about React and GraphQL to help developers. State machines offer a much better-organized way to manage state in React applications and they’re easy to scale compared to other alternatives. This method is known by many names but often is called a finite-state machine or even just a state machine. A state that has a substate is called a compound state. He also created the 33 JavaScript Concepts. xstate has a lot of features worth mentioning that we won’t cover much in this article (since we’ll only begin to scratch the surface on statecharts): hierarchical machines, parallel machines, history states, and guards, just to name a few. In this case, we have a pretty flat component tree beneath our provider (Auth.Provider), but remember that context allows that value to be available to any component beneath our provider in the component tree, regardless of depth. the callback function will be scheduled by React to fire on a later phase(see definition above). Usage with React. The application’s It seems like every React blog article, Tweet or Reddit post mentions them. In our traffic light example, the input is our timer. We’ll start in the initial state. xstate is the core package, as we need this to create our state machines. So, let’s create our first states. Modeling the Machine One state at a time, without any errors. It is a mathematical model that be in one a few finite states. We’ll start by defining the context for our application, then creating a stateful component (our provider) that will contain our authentication state machine, along with information about the current user and a method for the user to logout. This concept isn’t just limited to technology, it’s a fundamental part of how everything works: I’ve made the parallel with an application that I worked on. We’re going to give the id of lightMachine, and the initial state of our traffic light state machine will be green. This property will change our state when a transition occurs. Then, depending on the state of our application, we’re rendering either the dashboard or the login form for the user. Using finite state machines with React doesn’t have to be limited to authentication, nor does it have to be limited to the context API. To change our state, we’ll simply put an onClick method and use the send function, passing the next target which is YELLOW. To demonstrate what a timed automaton is I will use XState with React. Using Finite State Machines to Simplify State With React. react-automata has the added benefit of being able to automagically generate Jest tests for your components. So, without further ado, let’s dig into some code! But we know that it still happens a lot. See Trademarks for appropriate markings. We can make that transition by calling appMachine.transition('loggedOut', 'SUBMIT'). That’s where we get trapped and start to create side effects and unexpected bugs. For our application, we’re going to set up a few defaults: authState which will be the authentication state of the current user, an object called user which will contain data about our user if they’re authenticated, then a logout() method that can be called anywhere in the app if the user is authenticated. Let's take a look at how we can use state machines in our React apps by building a simple toggle machine. Referring back to the code above now, we define our initial application state — which we’re calling loggedOut since we’ll want to show the login screen on an initial visit. That was another big chunk of code, so let’s walk through each method again. Handling all that state logic data in a simple, powerful, consistent way, while avoiding side effects and bugs is a challenge that we face daily. We learned how state machines work, the advantages that finite state machines have over the common state management that we’re used to working with, and the differences between finite state machines and statecharts. If you’re interested in diving deeper into complex user interfaces using finite state machines, David Khourshid has a related article here on CSS-Tricks worth checking out. There isn’t another state possibility. XState is a JavaScript/TypeScript library to create finite state machines and statecharts. XState and finite state machines make a lot of sense to create better applications when you’ll have a lot of different states. That diagram was generated from this code using David Khourshid’s xviz library — which can be used to visually explore the actual code that powers your state machines. In this article, we learned more about a very important concept of computer science known as finite state machines. With a very simple example, we can understand how finite state machines work. Whenever the timer hits a specific amount of seconds, it transitions to another state. A timed automaton is a finite-state machine extended with clock variables. Uses the same format as useEffect: Effects are triggered when the state machine enters a given state. So, now that we’ve had a little bit of an introduction to both Context and xstate, let’s talk about the approach we’ll be taking. Thank you for your continued interest in Progress. A stateless finite state machine library might sound a bit strange, but essentially what it means is that xstate only cares about the state and transition that you pass it — meaning it’s up to your application to keep track of its own current state. Inside this object is where we’re going to create all the transitions and events for our finite state machine. In the transition() method, we’re doing a few important things. The context provider will be the component that sits at the top level of our application and houses all the data related to an authenticated — or unauthenticated — user. Very simple. So, let’s create our context to understand how it works. Very simple. In this article, we’ll tackle building something that most applications on the web use: authentication. State machine helps me structure my app into states, transitions and events so that my app becomes more predictive and eliminates any unexpected bugs or states. It is a mathematical model that be in one a few finite states. In our visualizer, this is how our finite state machine is looking: By clicking in our transitions, we can see our state changing, and our finite state machine is working as expected. But how we can do that? Typically, I prefer to model each stateful component with its own state machine and colocate that code alongside my component code. When we create context, we get a Provider and Consumer pair. state - Represents the current state of the machine as an XState State object. Along with our loggedOut and loggedIn states, we’ve defined some actions that we want to fire when our application enters or exits those states. We can use this visualizer to see how our finite state machine is working and if we have any errors. Due to this finite and deterministic nature, we can use state diagrams to visualize our application — before or after it’s been built. Next, we have to add the xstate and @xstate/react libraries by running the command below: yarn add xstate@latest @xstate/react. Statecharts are more scalable and consistent than simple state machines, and they come with some expensive features to help more complex systems. This is where the useMachine hook provided by @xstate/react comes in handy. One of the main features of statecharts is that they have a hierarchy state and each state can have substates. Now that we know about state machines and how they work, let’s find out how we can use them in our React apps. The machine used should always be decoupled from implementation details; e.g., it should never know that it is in React (or Vue, or Angular, etc. This way, once a user has authenticated, we can set relevant details about that user — username, email, id, etc. Context can be defined as “quantitative data”. Progress, Telerik, Ipswitch, and certain product names used herein are trademarks or registered trademarks of Progress Software Corporation and/or one of its subsidiaries or affiliates in the U.S. and/or other countries. State machines make the second category virtually disappear. Let’s name this machine lightMachine and use the Machine object: Each Machine should have an id and an initial state. We’re using the authState context to determine whether or not to show our login button in a disabled, loading state. … FAIL: { A traffic light has only three states: green, yellow and red. So, when you see someone else talking about statecharts, don’t get confused—they’re just an extension of a finite state machine with a few extra powerful features. We now have our finite state machine working fine, so let’s get started using it in React and see how it works. We can understand it like strings, functions, objects, etc. We have a timer, and, after the timer hits 30 seconds, the state will change to yellow. The most straightforward way of using XState with React is through local component state. The first thing we need to do is define our application context and set it up with some default values. loggedOut: { It is used to avoid excessive "prop drilling" among other things. From green to yellow, from yellow to red, from red to green. send - A function that sends events to the running service. To start with finite state machines in React, let’s first understand how they work, their purpose and why they are one of the most powerful ways to handle state logic in an application. causes the brain to take new transitions to … Why state machine? The returned state is current, and the send function is to update our state using our actions. In fact, state machines can be used with just about any un-opinionated state management tool. If you wish to change this at any time you may do so by clicking here. Storing state within a UI library ensures that changes won’t be missed and will trigger re-renders. This is the approach of a library called React-Automata that uses a higher-order component initiated by withStatechart. 1 improvement you could make would be to remove onEntry: ['error'] from loggedOut state. In this post, I thought it would be interesting to implement an old data modeling process with the new hooks API. Now, take a look at your code. Let’s break it down into manageable chunks by taking a look at each method of this class individually. Don’t worry, we’ll cover what each method does in just a moment. So, let’s get started with XState and learn how we can create our first finite state machine and achieve a better level of state logic in our apps. I’m pretty sure that you can identify a few small finite machines in your code very easily. When you have certain data that is needed by a variety of components, you can end up doing what’s known as prop drilling — passing data through multiple levels of the component tree to get the data to a component that needs it. To do so, let's run the following command on the terminal to create a fresh React App. Try for free! To change the state, we’ll use the send function from our useMachine hook. In more practical terms, though, a state machine is characterized by a list of states with each state defining a finite, deterministic set of states that can be transitioned to by a given action. If you have important information to share, please, David Khourshid has a related article here. We have a finite number of states and an initial state. A Confirmation Modal in React. Then we pass all that as an object to the Machine() function, which is imported from xstate. XState implements state machines and statecharts in JavaScript (and React, but it can be used with any framework). Let’s set the scene a little bit. It reacts to its state machine brain and: implements the actions/services/effects that the brain wants to take place. Previously, I wrote about using the state pattern to manage application state. So, for example, if we have a component nested three or four levels down and we want to display the current user name, we can just grab that out of context, rather than drilling it all the way down to that one component. From there, the loading state will either move the user along as an authenticated user or send them back to the login screen and display an error message. The React component is the body. A finite state machine can only be in one state at a given time; it’s impossible to be in more than one. component — since it will only ever be rendered if the user is logged in. Oh my! Use a machine service to persist state (https://xstate.js.org/docs/guides/interpretation.html).