Что произойдет, если вы отправите событие, которого нет в React Xstate?

Возьмите этот конечный автомат:

{
  initial: "foo",
  states: {
    foo: {
      on: { BAR: "bar" }
    },
    bar: {
      on: { FOO: "foo" }
    }
  }
}

И в моем компоненте я делаю это:

import { useMachine } from "@xstate/react";

export default function() {
  const [current, send] = useMachine(machine);

  useEffect(() => {
    send("BAR");
  }, []);

  return (
    <>
      Hello World  
    </>
  );
}

Это совершенно правильный код, и машина переключится в состояние «бар». Теперь, что произойдет, если я сделаю это?

useEffect(() => {
  send("QUX");
}, []);

Событие QUX не определено в машине.


person Paul Razvan Berg    schedule 17.11.2019    source источник


Ответы (2)


В этом сценарии интерпретатор конечного автомата должен игнорировать незапланированное событие. Так работает государственная машина. Оценка перехода не будет выполняться, если событие не может быть найдено.

Согласно определению конечного автомата.

Конечный автомат — это конечный набор состояний, которые могут переходить друг в друга детерминистически из-за событий.

Запланированные события приводят к запланированным переходам (если охранники прошли).

Учтите, что если вы находитесь в состоянии foo, но событие "QUX" определено выше в иерархии состояний, интерпретатор найдет его и оценит определенный там переход.

В иерархической машине приоритеты переходов определяются тем, насколько глубоко они находятся в дереве; более глубокие переходы более специфичны и поэтому имеют более высокий приоритет. Это работает аналогично тому, как работают события DOM: если вы нажмете кнопку, обработчик события щелчка непосредственно на кнопке будет более конкретным, чем обработчик события щелчка в окне.

Подробнее об этом случае можно узнать здесь, в главе «Переходы» документов Xstate.

person Tdk    schedule 09.01.2020

Если строгий режим не включен (он не включен по умолчанию), «StateNode» попытается перейти в соответствующее состояние-кандидат на основе события, не найдет ничего и ничего не сделает.

Вот ссылка на код, который определяет, будет ошибка или нет, и небольшой фрагмент:

if (this.strict) {
  if (!this.events.includes(_event.name) && !isBuiltInEvent(_event.name)) {
    throw new Error(
      `Machine '${this.id}' does not accept event '${_event.name}'`
    );
  }
}
person TameBadger    schedule 09.01.2020