State Management

Машины: когда уместны

Команда добавляет XState в проект, потому что прочитала статью про машины состояний, и оборачивает в машину обычный переключатель темы: два состояния, один переход, пятнадцать строк конфигурации там, где хватило бы useState с булевым флагом. Через месяц в том же проекте экран оплаты живёт на трёх useState и каскаде if-else, где половина переходов невозможна, но код их допускает - и именно там машина была бы спасением. Инструмент перепутали местами с задачей. Машина состояний это не галочка зрелости, а ответ на конкретный вопрос: сколько у потока правил и насколько больно их нарушить.

  • Stripe Checkout: оплата проходит через множество состояний (ввод, 3D Secure, обработка, успех, отказ, ретрай), где запрещённые переходы стоят денег
  • Онбординг-визарды в Notion и Linear: шаги с условиями, ветвлениями и возможностью вернуться назад - классический кейс для машины
  • Переподключение websocket в Slack и Figma: connecting, connected, reconnecting с backoff, failed - поток с ретраями и таймерами
  • Видеоплееры (YouTube, Twitch): idle, buffering, playing, paused, ended плюс переходы между ними по строгим правилам
  • Простые тогглы, аккордеоны, дропдауны: один булев флаг, где машина только добавляет церемонии без выгоды

Предварительные знания

  • Машина состояний: что такое состояния, события и переходы
  • Опыт с useState и булевыми флагами для простого UI-состояния
  • Понимание, что такое невозможное состояние (например, isLoading и isError одновременно true)
  • Введение в машины состояний

Где машина состояний выигрывает

Машина состояний окупается, когда у потока много состояний и переходы между ними подчинены правилам. Главная выгода - запрет невозможных состояний. В коде на булевых флагах ничто не мешает выставить isLoading и isError одновременно в true, хотя по смыслу это бессмыслица. Машина делает такую комбинацию недостижимой: актор в каждый момент находится ровно в одном состоянии, а переход разрешён только если он явно описан.

  • Оплата: ввод данных, 3D Secure, обработка, успех, отказ, повторная попытка - переходы строгие, цена ошибки прямая
  • Онбординг-визард: шаги с ветвлением, возврат назад, валидация перед переходом дальше
  • Переподключение websocket: connecting, connected, reconnecting с экспоненциальным backoff, failed после N попыток
  • Медиаплеер: idle, buffering, playing, paused, ended с правилами, какой переход откуда возможен

Общее у всех этих кейсов: переходов больше горстки, у них есть условия, и неверный переход (оплатить дважды, проиграть до загрузки) приводит к реальному вреду. Машина превращает эти правила из комментариев в коде в саму структуру, которую невозможно нарушить.

В чём главная практическая выгода машины состояний для потока оплаты?

Где машина это перебор

Обратная сторона: если у состояния два значения и один переход между ними, машина только добавляет церемонии. Переключатель темы, открытие дропдауна, раскрытие аккордеона - это булев флаг. Завернуть его в createMachine значит написать пятнадцать строк конфигурации, импортов и типов там, где useState решает задачу одной строкой, и при этом ничего не выиграть: невозможных состояний тут нет, ломать нечего.

  • Машина оправдана — Состояний больше горстки, переходы условны, неверный переход вредит. Оплата, онбординг, реконнект, плеер. Правила переходов стоит зафиксировать в структуре.
  • Машина это перебор — Два-три значения, один-два перехода без условий, цена ошибки нулевая. Тоггл, дропдаун, таб. useState или useReducer закрывают вопрос.

Распространённая ошибка - тащить XState в проект как признак зрелости и оборачивать в машину всё подряд. Перебор стоит реально: лишний вес бандла, выше порог входа для команды и больше кода на ровном месте. Машина должна заслужить своё присутствие сложностью потока.

Для какого из случаев машина состояний скорее всего избыточна?

Как принять решение

Решение сводится к нескольким наблюдаемым сигналам. Если в компоненте накапливается каскад булевых флагов и появляются проверки вида 'если loading и при этом не error и при этом не success' - это запах невозможных состояний, которые лучше описать машиной. Если в потоке есть переходы, которые код допускает, но логика запрещает (вернуться к оплате после успеха), машина закроет эту дыру структурно.

СигналЧто значитРешение
Один булев флаг, один переходПростое UI-состояниеuseState
Несколько флагов, простые комбинацииПереходов мало, правил почти нетuseReducer
Каскад флагов, проверки 'loading и не error'Невозможные состояния достижимыМашина состояний
Запрещённые переходы, ретраи, таймерыСложный поток с правиламиМашина состояний

Промежуточный вариант - useReducer. Он даёт явные переходы через действия без веса и кривой обучения XState. Если переходов немного и невозможных состояний нет, reducer часто закрывает потребность, не доводя до полноценной машины.

Какой признак в коде сильнее всего намекает, что пора заменить набор useState машиной состояний?

Связь с другими темами

Урок про критерий выбора. Дальше тема расходится так:

  • Введение в машины состояний — База, на которой строится разговор: без понятия переходов нет и разговора об их сложности
  • XState: акторы — Когда поток сложный, его часто дробят на акторов, и тогда машина оправдана вдвойне

Итог

  • Машина состояний оправдана, когда переходов много, у них есть правила и нарушение правила стоит дорого (оплата, онбординг, websocket с ретраями)
  • Главная выгода - невозможные состояния становятся непредставимыми: машина не даёт уйти в комбинацию, которой не существует по логике потока
  • Сигналы 'пора брать машину': каскад булевых флагов, проверки вида 'если loading и при этом error', запрещённые переходы, которые код всё равно допускает
  • Простой тоггл, дропдаун, аккордеон обходятся одним useState. Машина тут добавляет конфигурацию и церемонию без выгоды
  • Критерий - сложность потока и цена ошибки, а не мода на машины состояний

Связанные уроки

  • sm-25-state-machines-intro — Чтобы рассуждать о границе применимости, нужно базовое понятие машины состояний и её переходов
  • sm-28-xstate-actors — Сложные потоки часто разбиваются на акторов, поэтому критерий уместности машины и тема акторов идут рядом
Машины: когда уместны

0

1

Войти