Параллельные состояния
Состояние может объявлять регионы parallel — набор независимых под-машин, которые все становятся активными при входе в родительское состояние и уничтожаются при выходе из него.
const editor = defineMachine({
id: 'editor',
initial: 'editing',
states: {
editing: {
parallel: {
saving: {
initial: 'idle',
states: {
idle: { on: { START_SAVE: { target: 'saving' } } },
saving: { on: { SAVE_DONE: { target: 'saved' } } },
saved: {},
},
},
validation: {
initial: 'valid',
states: {
valid: { on: { INVALIDATE: { target: 'invalid' } } },
invalid: { on: { VALIDATE: { target: 'valid' } } },
},
},
},
},
idle: {},
},
})send() доставляет каждое событие во все активные регионы. Каждый регион обрабатывает его независимо.
const { matches, send } = useMachine(editor)
matches('editing') // основное состояние
matches({ saving: 'idle' }) // проверка региона
matches({ validation: 'valid' }) // другой регион
await send('INVALIDATE')
matches({ validation: 'invalid' }) // true
matches({ saving: 'idle' }) // всё ещё true — не затронутоРазрешение конфликтов контекста: переход каждого региона сообщает только о полях, которые реально затронули его собственные actions — нетронутое поле никогда не перезаписывается устаревшей копией соседнего региона. Когда два региона действительно возвращают Partial<context>, затрагивающий одно и то же поле, побеждает последний регион в порядке объявления. В dev-режиме выводится console.warn с именами конфликтующих регионов и полем.
Ограничение: параллельные регионы поддерживают один уровень вложенности. Регионы не могут сами содержать parallel. Это осознанное решение для контроля сложности.