Sviatoslav Oleksiv

Creating Your First State Machine

In the previous lesson, we successfully set up XState in a React application. Now, it’s time to dive deeper and create your first state machine. A state machine allows you to model different states an application or component can be in, and define how it transitions from one state to another based on events.

In this lesson, you will learn:

Let’s get started!

What is a State Machine?

A state machine is a conceptual model that describes the different states an application or component can be in, along with the events that trigger transitions between these states. In XState, a state machine consists of:

Step 1: Defining Your First State Machine

Let’s define a basic state machine for a toggle button that can be in two states: "inactive" or "active". When clicked, it toggles between these states.

Code Example: Basic Toggle Machine

import { createMachine } from 'xstate';

const toggleMachine = createMachine({
  id: 'toggle',
  initial: 'inactive',  // The starting state
  states: {
    inactive: {
      on: { TOGGLE: 'active' }  // Transitions to 'active' on the 'TOGGLE' event
    },
    active: {
      on: { TOGGLE: 'inactive' }  // Transitions back to 'inactive' on the 'TOGGLE' event
    }
  }
});

export default toggleMachine;

Explanation:

Step 2: Visualizing the State Machine

Here’s a visual representation of our simple state machine:

+-----------+     TOGGLE     +----------+
| Inactive  |  ----------->  |  Active  |
+-----------+                +----------+
     ^                            |
     |         TOGGLE             v
     +-------------------------+

The TOGGLE event moves the state back and forth between "inactive" and "active."

Step 3: Integrating the State Machine in React

Next, we’ll integrate the state machine into a React component using XState’s useMachine hook. This hook allows us to run the state machine inside the component and handle its state transitions.

Code Example: Toggle Button Component

import React from 'react';
import { useMachine } from '@xstate/react';
import toggleMachine from './toggleMachine';

const ToggleButton = () => {
  const [state, send] = useMachine(toggleMachine); // useMachine hook to use the state machine

  return (
    <div>
      <p>The current state is {state.value}</p>  {/* state.value returns 'inactive' or 'active' */}
      <button onClick={() => send('TOGGLE')}>  {/* send('TOGGLE') triggers the TOGGLE event */}
        Toggle
      </button>
    </div>
  );
};

export default ToggleButton;

Explanation:

Step 4: Running the Application

Now, run your React application:

npm start

When the app opens in your browser, you’ll see a button that toggles between the "inactive" and "active" states when clicked. The text displayed will change depending on the current state.

Step 5: Adding Actions to State Transitions

In XState, you can also define actions that get executed whenever a state transition occurs. For example, let’s log a message to the console every time the state changes.

Code Example: Adding Actions

import { createMachine } from 'xstate';

const toggleMachine = createMachine({
  id: 'toggle',
  initial: 'inactive',
  states: {
    inactive: {
      on: {
        TOGGLE: {
          target: 'active',
          actions: () => console.log('Toggled to active')  // Action executed on transition
        }
      }
    },
    active: {
      on: {
        TOGGLE: {
          target: 'inactive',
          actions: () => console.log('Toggled to inactive')  // Action executed on transition
        }
      }
    }
  }
});

export default toggleMachine;

Explanation:

Conclusion

In this lesson, you created your first state machine using XState. You defined two states, "inactive" and "active", and handled transitions between them using the TOGGLE event. We also learned how to integrate the state machine into a React component and how to trigger events using the useMachine hook.

In the next lesson, we’ll explore how to handle more complex states and actions, including using context to manage additional data within the state machine.


Next Lesson: Using Context and Handling Side Effects in XState