Перейти к содержанию

События

Событие (event) — это то, что заставляет конечный автомат переходить из текущего состояния в следующее состояние.

API

Событие — это объект со свойством type, указывающим, к какому типу оно относится:

const timerEvent = {
  type: 'TIMER', // the convention is to use CONST_CASE for event names
};

В XState события, которые имеют только type, могут быть представлены только их строковым типом, как сокращение:

// equivalent to { type: 'TIMER' }
const timerEvent = 'TIMER';

Объекты событий также могут иметь другие свойства, которые представляют данные, связанные с событием:

const keyDownEvent = {
  type: 'keydown',
  key: 'Enter',
};

Отправка событий

Переход определяет, каким будет следующее состояние, учитывая текущее состояние и событие, определенные в его свойстве on: {...}. Это можно увидеть, передав событие в метод перехода:

import { createMachine } from 'xstate';

const lightMachine = createMachine({
  /* ... */
});

const { initialState } = lightMachine;

let nextState = lightMachine.transition(
  initialState,
  'TIMER'
); // string event
console.log(nextState.value);
// => 'yellow'

nextState = lightMachine.transition(nextState, {
  type: 'TIMER',
}); // event object
console.log(nextState.value);
// => 'red'

Многие нативные события, такие как события DOM, совместимы и могут использоваться напрямую с XState, указав тип события в свойстве type:

import { createMachine, interpret } from 'xstate';

const mouseMachine = createMachine({
  on: {
    mousemove: {
      actions: [
        (context, event) => {
          const { offsetX, offsetY } = event;
          console.log({ offsetX, offsetY });
        },
      ],
    },
  },
});
const mouseService = interpret(mouseMachine).start();

window.addEventListener('mousemove', (event) => {
  // event can be sent directly to service
  mouseService.send(event);
});

Нулевые события

Внимание

Синтаксис нулевого события ({on: {'': ...}}) будет устаревшим в версии 5. Вместо него следует использовать новый синтаксис always.

Нулевое событие (null event) — это событие, которое не имеет типа и происходит сразу после входа в состояние. В переходах оно представлено пустой строкой (''):

// contrived example
const skipMachine = createMachine({
  id: 'skip',
  initial: 'one',
  states: {
    one: {
      on: { CLICK: 'two' },
    },
    two: {
      // null event '' always occurs once state is entered
      // immediately take the transition to 'three'
      on: { '': 'three' },
    },
    three: {
      type: 'final',
    },
  },
});

const { initialState } = skipMachine;
const nextState = skipMachine.transition(
  initialState,
  'CLICK'
);

console.log(nextState.value);
// => 'three'

Существует много вариантов использования нулевых событий, особенно при определении переходов, когда (потенциально проходное) состояние сразу определяет, какое следующее состояние должно быть основано на защитных функциях:

const isAdult = ({ age }) => age >= 18;
const isMinor = ({ age }) => age < 18;

const ageMachine = createMachine({
  id: 'age',
  context: { age: undefined }, // age unknown
  initial: 'unknown',
  states: {
    unknown: {
      on: {
        // immediately take transition that satisfies conditional guard.
        // otherwise, no transition occurs
        '': [
          { target: 'adult', cond: isAdult },
          { target: 'child', cond: isMinor },
        ],
      },
    },
    adult: { type: 'final' },
    child: { type: 'final' },
  },
});

console.log(ageMachine.initialState.value);
// => 'unknown'

const personData = { age: 28 };

const personMachine = ageMachine.withContext(personData);

console.log(personMachine.initialState.value);
// => 'adult'