Self transition event

A context update can only be triggered by a state transition. A state transition in turn requires an event.

You may be wondering, how can we have a state transition with only 1 state?

State machines support what are called self-transitions. A self-transition is a transition that moves from the current state to itself:

When a state reacts to an event and transitions to itself, it is called a self-transition
When a state reacts to an event and transitions to itself, it is called a self-transition

We first define the "toggle" event same as before:

import { setup } from "xstate";

type Event = { type: "toggle" };
type Context = { toggleValue: boolean };
const initialContext: Context = { toggleValue: false };

const machine = setup({
  types: {
    events: {} as Event,
    context: {} as Context,
  },
}).createMachine({
  context: initialContext,
  initial: "Idle",
  states: {
    Idle: {}
  },
});

From the "Idle" state we intercept the "toggle" event and transition to the same state using target:

import { setup } from "xstate";

type Event = { type: "toggle" };
type Context = { toggleValue: boolean };
const initialContext: Context = { toggleValue: false };

const machine = setup({
  types: {
    events: {} as Event,
    context: {} as Context,
  },
}).createMachine({
  context: initialContext,
  initial: "Idle",
  states: {
    Idle: {
      on: {
        toggle: {
          target: "Idle",
          // Update context on "toggle" event
        },
      },
    },
  },
});

If target is omitted, XState will perform a self-transition by default.

Therefore, target in this example is not required.

In XState context updates are implemented using actions. Let's see how in the next lesson!