Skip to content

Latest commit

 

History

History
135 lines (106 loc) · 3.53 KB

machines.md

File metadata and controls

135 lines (106 loc) · 3.53 KB

Machines

:::warning These XState v4 docs are no longer maintained

XState v5 is out now! Read more about XState v5

🆕 Find more about creating machines using XState in our new docs. :::

A state machine is a finite set of states that can transition to each other deterministically due to events. To learn more, read our introduction to statecharts.

Configuration

State machines and statecharts alike are defined using the createMachine() factory function:

import { createMachine } from 'xstate';

const lightMachine = createMachine({
  // Machine identifier
  id: 'light',

  // Initial state
  initial: 'green',

  // Local context for entire machine
  context: {
    elapsed: 0,
    direction: 'east'
  },

  // State definitions
  states: {
    green: {
      /* ... */
    },
    yellow: {
      /* ... */
    },
    red: {
      /* ... */
    }
  }
});

The machine config is the same as the state node config, with the addition of the context property:

  • context - represents the local "extended state" for all of the machine's nested states. See the docs for context for more details.

Options

Implementations for actions, delays, guards, and services can be referenced in the machine config as a string, and then specified as an object in the 2nd argument to createMachine():

const lightMachine = createMachine(
  {
    id: 'light',
    initial: 'green',
    states: {
      green: {
        // action referenced via string
        entry: 'alertGreen'
      }
    }
  },
  {
    actions: {
      // action implementation
      alertGreen: (context, event) => {
        alert('Green!');
      }
    },
    delays: {
      /* ... */
    },
    guards: {
      /* ... */
    },
    services: {
      /* ... */
    }
  }
);

This object has 5 optional properties:

  • actions - the mapping of action names to their implementation
  • delays - the mapping of delay names to their implementation
  • guards - the mapping of transition guard (cond) names to their implementation
  • services - the mapping of invoked service (src) names to their implementation
  • activities (deprecated) - the mapping of activity names to their implementation

Extending Machines

Existing machines can be extended using .withConfig(), which takes the same object structure as above:

const lightMachine = // (same as above example)

const noAlertLightMachine = lightMachine.withConfig({
  actions: {
    alertGreen: (context, event) => {
      console.log('green');
    }
  }
});

Initial Context

As shown in the first example, the context is defined directly in the configuration itself. If you want to extend an existing machine with a different initial context, you can use .withContext() and pass in the custom context:

const lightMachine = // (same as first example)

const testLightMachine = lightMachine.withContext({
  elapsed: 1000,
  direction: 'north'
});

::: warning This will not do a shallow merge of the original context, and will instead replace the original context with the context provided to .withContext(...). You can still "merge" contexts manually, by referencing machine.context:

const testLightMachine = lightMachine.withContext({
  // merge with original context
  ...lightMachine.context,
  elapsed: 1000
});

:::