Начнём¶
Наш первый конечный автомат¶
Предположим, мы хотим смоделировать Promise как конечный автомат. Сначала установите XState с помощью NPM или Yarn:
npm install xstate --save
Если вы используете VSCode, вам следует установить наше расширение VSCode, чтобы вы могли визуализировать автомат, который вы строите, в процессе работы.
Затем в своем проекте импортируйте createMachine
— функцию, которая создает конечный автомат.
import { createMachine } from 'xstate';
const promiseMachine = createMachine(/* ... */);
Мы передадим конфигурацию автомата createMachine
. Нам потребуется предоставить:
id
— для идентификации автоматаinitial
— для указания узла начального состояния, в котором должен находиться этот автоматstates
— для определения каждого из дочерних состояний:
import { createMachine } from 'xstate';
const promiseMachine = createMachine({
id: 'promise',
initial: 'pending',
states: {
pending: {},
resolved: {},
rejected: {},
},
});
Затем нам нужно добавить переходы к узлам состояния.
import { createMachine } from 'xstate';
const promiseMachine = createMachine({
id: 'promise',
initial: 'pending',
states: {
pending: {
on: {
RESOLVE: { target: 'resolved' },
REJECT: { target: 'rejected' },
},
},
resolved: {},
rejected: {},
},
});
Нам также нужно пометить узлы состояния resolved
и rejected
, как узлы конечного состояния, поскольку автомат Promise прекращает работу, как только достигает этих состояний:
import { createMachine } from 'xstate';
const promiseMachine = createMachine({
id: 'promise',
initial: 'pending',
states: {
pending: {
on: {
RESOLVE: { target: 'resolved' },
REJECT: { target: 'rejected' },
},
},
resolved: {
type: 'final',
},
rejected: {
type: 'final',
},
},
});
Теперь наш конечный автомат готов к визуализации. Вы можете скопировать / вставить приведенный выше код и визуализировать его в Stately Viz. Вот как это будет выглядеть:
Запуск нашего автомата¶
То, как мы запускаем наш автомат, зависит от того, где мы планируем его использовать.
В Node.js или Vanilla JS¶
Чтобы интерпретировать автомат и заставить его работать, нам нужно добавить интерпретатор. Этот код создает службу:
import { createMachine, interpret } from 'xstate';
const promiseMachine = createMachine({
/* ... */
});
const promiseService = interpret(
promiseMachine
).onTransition((state) => console.log(state.value));
// Start the service
promiseService.start();
// => 'pending'
promiseService.send({ type: 'RESOLVE' });
// => 'resolved'
В React¶
Если бы мы хотели использовать наш автомат внутри компонента React, мы могли бы использовать хук useMachine
:
Дополнительно нам нужно установить пакет
@xstate/react
import { useMachine } from '@xstate/react';
const Component = () => {
const [state, send] = useMachine(promiseMachine);
return (
<div>
{/** You can listen to what state the service is in */}
{state.matches('pending') && <p>Loading...</p>}
{state.matches('rejected') && <p>Promise Rejected</p>}
{state.matches('resolved') && <p>Promise Resolved</p>}
<div>
{/** You can send events to the running service */}
<button onClick={() => send('RESOLVE')}>
Resolve
</button>
<button onClick={() => send('REJECT')}>
Reject
</button>
</div>
</div>
);
};