Getting started with Finite State Machine using X-state.
Tags: react, programming, javascript, beginners
Published: 2023-04-17 07:14:12

## Introduction 
 State management in a developer's journey can be hell and bliss, and this depends on the library one chose and how well he grasps the logic behind it right? I must say using a state manager never got better when you can visualize your code logic and decide the kind of beans you're cooking.

In today's session, I'll show us how spectacularly the X-state machine works in practice, and how generously it can make your experience in development worthwhile.

### What is a Finite State Machine
The finite state machine can be seen as a mathematical “model” that performs a certain computational activity that assumes an initial state and spins through different[specified] states and back to the normal [accepting state]...
More explanation can be found in my previous article ["The finite state machine"](https://asapa1.hashnode.dev/the-finite-state-machine)

### What is X-State
Unlike redux, recoil, Zustand, and a million others, X-State is a library that helps you create finite states, have a visual interpretation, and also execute the logic seamlessly where for instance you will not have to wrap your whole app in a provider, store something or dispatch anything. It's just easy to use and maintain. you can find more explanations [here](https://xstate.js.org/docs/)

## Getting Started 
In this guide we will start by learning how to make a simple dark/light mode, and furtherly a traffic light for our react application all from scratch.
You can find all the working code [here](https://github.com/asapconet/react-xState-finite-machine.git) on my Github.[_drop me a star thanks!_]

### Setting up
We need to create our app to run this so let's run this;
```
yarn create react-app react-xstate-finite-machine
```
or 
```
npx create react-app react-xstate-finite-machine
```
Moving forward, we add the `xstate` package to the app;
```
yarn add xstate @xstate/react
```
Let's run our app `yarn start` or `npm start`[if you are using npm to setup], while our app is building.

Create a file with the name you wish and that is where we will initialize the state like so;
```javascript
import { Machine } from "xstate";

export const switchThemes = Machine({
  id: "themes",
  initial: "light",
  states: {
    light: {
      on: { SWITCH: "dark" },
    },
    dark: {
      on: { SWITCH: "light" },
    },
  },
});
```
_Break down_
> **id:** just like any state manager it is the name of the name assigned to the state.
**initial:** that's the [initial]assignment name to the state we want to work with.
**states:** this is the area we're the state recide.[light&dark]
**switch & on:** that is what we use to fire the action of switching the themes.

#### ShowTime
Now it's time to visualize the beans we have been cooking, and `x-state` provides us with a tool called the [visualizer](https://xstate.js.org/viz/) which will show us how our state will logically work.

![state in action](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4sho6gmfv6c52z5whfz9.png)
Now you can see that the logic circle began from the initail state of `light` and when a `switch` is invoked it'll change back to `dark`. Nicely yhh?

Back to our code, we would like to see our state in action, so we call our state component to `App.js`, also in order for the state to function fully we have to call the `useMachine` hook from the `x-state` library and we should have something like this.
```javascript
import "./App.css";
import { useMachine } from "@xstate/react";
import { switchThemes } from "./states/darkLightSwitch";

function App() {
  const [current, send] = useMachine(switchThemes);

  const handleSwitch = () => {
    send("SWITCH");
  };

  return (
    <div
      className={
        current.matches("light") ? "light-theme body" : "dark-theme body"
      }
    >
      <button onClick={handleSwitch}>
        {current.matches("light") ? "light" : "dark"}
      </button>
      <h1>{current.matches("light") ? "Light Turnels" : "Dark Moments"}</h1>
    </div>
  );
}

export default App;
```
**NB** the `light-theme` & `dark-theme` are my CSS classes and they are in their separate folder.

Exciting, isn't it? Now let's get even deeper.

### Traffic Lights
Having learned how to add themes to your app why don't we go deeper yeah?
Our traffic lights will assume this looks for now;

![inital app looks](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ku99odvvyioxmei0td14.png)

We will add a traffic light system into the app and follow prior setup guides for the `dark & light` the theme, we will be having our trafficking[_excuse my french_] light state like so;

```javascript
import { createMachine } from "xstate";

export const trafficMachine = createMachine({
  id: "trafficLights",
  initial: "stop",
  states: {
    stop: {
      on: {
        NEXT: {
          target: "ready",
        },
      },
    },
    ready: {
      on: {
        NEXT: {
          target: "go",
        },
      },
    },
    go: {
      on: {
        NEXT: {
          target: "stop",
        },
      },
    },
  },
});
```
Yet again visualizer to confirm our act;

![trafic light preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6f6zc08w1m3d3lr70lm9.png)

Moving forward we will call the state in our application and this time around we will be using our darling `useEffect` to set our timer for the traffic light action, and the entire code should look like this;

```javascript
import "./App.css";
import { useEffect } from "react";
import { useMachine } from "@xstate/react";
import { switchThemes } from "./states/darkLightSwitch";
import { trafficMachine } from "./states/trafficControlState";

function App() {
  const [state, send] = useMachine(switchThemes);
  const [current, push] = useMachine(trafficMachine);

  const handleSwitch = () => {
    send("SWITCH");
  };

  useEffect(() => {
    let trigger = () => {
      push("NEXT");
    };
    let timer = setInterval(() => {
      trigger();
    }, [3000]);
    return () => clearInterval(timer);
  });

  return (
    <div
      className={
        state.matches("light") ? "light-theme body" : "dark-theme body"
      }
    >
      <div className="container">
        <button onClick={handleSwitch}>
          {state.matches("light") ? "light" : "dark"}
        </button>
        <h1>{state.matches("light") ? "Light Turnels" : "Dark Moments"}</h1>
      </div>
      <div>
        <ul className="light-container">
          <li className={current.matches("stop") && "red"}>
            {current.matches("stop") && "STOP"}
          </li>
          <li className={current.matches("ready") && "yellow"}>
            {current.matches("ready") && "READY"}
          </li>
          <li className={current.matches("go") && "green"}>
            {current.matches("go") && "GO"}
          </li>
        </ul>
      </div>
    </div>
  );
}

export default App;
```
You will notice the call of `useMachine`hook twice, now that's because x-state will not allow you to call more than two actions to the function like our normal `useState` wouldn't.

Check out the app in different modes.

![active trafic on dark mode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mbgakc14dly6zrs19wrr.png)
![active trafic on light mode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dd4f1e7p4n1ic3qp7z53.png)


#### Voilà we have our genius mode activated yhh, do well to share with others. Merci beaucoup!