State machine advent: Invoking a state machine in React (5/24)
Tags: javascript, typescript, react
Published: 2019-12-05 16:02:54

After having created an abstract state machine that models the behavior of our application, it is now time to wire the machine to a React component. Our invoked state machine (also known as **service**) should dictate the current state of our component at all times.

If you want to jump right into the [CodeSandbox](https://codesandbox.io/s/awesome-dewdney-7isp2), feel free to do so. Below you can find all the relevant pieces of code with a brief explanation. 

Here is the light switch machine we've created again.

```javascript
import { Machine } from 'xstate';

const lightSwitchMachine = Machine({
  id: 'lightSwitch',
  initial: 'inactive',
  states: {
    inactive: {
      on: {
        TOGGLE: 'active'
      }
    },
    active: {
      on: {
        TOGGLE: 'inactive'
      }
    },
  }
});
```

If we want to use the machine within a React component, we need to install a tiny package called `@xstate/react`. It exports a couple of hooks with which we can invoke state machines and friends. 

```javascript
import React from 'react';
import { useMachine } from '@xstate/react';
import Switch from 'react-switch';

const LightSwitch = () => {
  const [state, send] = useMachine(lightSwitchMachine);

  return (
    <Switch
      onChange={() => send({ type: 'TOGGLE' })}
      checked={state.matches('active')}
      aria-label='Toggle me'
    />
  );
};
```

Don't mind the imported `<Switch />` component. We are merely using it so that we don't have to write custom CSS to get a decent looking switch.
Instead, I want to focus on the `useMachine` hook. You can find its full API specification [here](https://xstate.js.org/docs/packages/xstate-react/#api). It takes in our machine as an argument and returns an array. The first entry is the `state` object of our invoked machine. It is **not** a string value telling us whether the service is in the `active` or `inactive` state. It's an object with a lot of properties to access the internals of our invoked state machine. Very rarely, we'll be interested in anything other than `state.matches`.

___

As an aside, if you don't want to worry about the other properties, you could totally just destructure the one you'll need.

```javascript
// array destructering, object destructering and aliasing to isStateMatching 
const [{matches: isStateMatching}, send] = useMachine(lightSwitchMachine);

// then use it like this
isStateMatching('active') 
```
___

Going back to our example from above, `matches()` is a function that returns a boolean. Use it to assert whether the current state of our service, matches the state node passed as a first argument.  

`checked={state.matches('active')}` 

In plain English, this line is saying: If our invoked machine is in the active state, pass `true` for the `checked` prop of our `Switch` component. If our machine is in any other state, pass `false`.  

The last thing that we need to cover for today is the `send` function. If you've used the  `useReducer` hook or Redux in the past, you might be used to calling this function `dispatch`. Even though you should be able to ditch Redux at the end of the series, you can continue to use the name `dispatch` if it works for you. 

As the name indicates, it is used to send events to the invoked machine which can react to the event by transitioning from one state to another. There are two ways to send events. 

You can either pass an object to the `send` function and set the event name as a value of the `type` key. This is how I used it in the example above `send({type: 'TOGGLE'})`, or you can just pass the event name as a string value `send('TOGGLE')`.

I hope this post gave you a brief overview on how to invoke an abstract machine and use the service within a React component. I'm very excited about the post tomorrow as we'll solidify our learnings from today by looking at the differences between an implicit and explicit state machine.

### About this series
Throughout the first 24 days of December, I'll publish a small blog post each day teaching you about the ins and outs of state machines and statecharts.

The first couple of days will be spent on the fundamentals before we'll progress to more advanced concepts.