В чем разница между redux и конечным автоматом (например, xstate)?

93

Я работаю над исследованием одного клиентского приложения средней сложности. На данный момент он написан на чистом javascript, в нем много различных событийно-ориентированных сообщений, соединяющих несколько основных частей этого приложения.

Мы решили, что нам нужно реализовать какой-то контейнер состояний для этого приложения в рамках дальнейшего рефакторинга. Раньше у меня был некоторый опыт работы с redux и ngrx store (которые фактически следуют тем же принципам).

Redux - это вариант для нас, но один из разработчиков предложил использовать библиотеку на основе конечного автомата, в частности конечного библиотеку xstate .

Я никогда не работал с xstate, поэтому мне это показалось интересным, и я начал читать документацию и рассматривать разные примеры. Выглядело многообещающе и мощно, но в какой-то момент я понял, что не вижу существенной разницы между ним и redux.

Я часами пытался найти ответ или любую другую информацию, сравнивая xstate и redux. Я не нашел какой - либо четкой информации, за исключением некоторых статей , как «получить от Redux к государственной машине» , или ссылки на библиотеки сосредоточены на использовании Redux и xstate вместе (довольно странно).

Если кто-то может описать разницу или сказать мне, когда разработчикам следует выбрать xstate - добро пожаловать.

Артем Архипов
источник
3
Официальные документы на самом деле говорят, что вы должны относиться к своим редукторам redux
Янник Хаманн,
Я думаю, что упомянутые вами библиотеки могут быть предназначены для использования xstate в качестве системы управления эффектами (альтернатива thunk, saga, epic и т. Д.)
Альфред Янг

Ответы:

205

Я создал XState, но я не собираюсь сообщать вам, использовать ли одно вместо другого; это зависит от вашей команды. Вместо этого я попытаюсь выделить некоторые ключевые отличия.

  • Redux - это, по сути, контейнер состояний, в котором события (называемые действиями в Redux) отправляются редуктору, который обновляет состояние.
  • XState также является контейнером состояния, но он отделяет конечное состояние (например "loading", "success") от «бесконечного состояния» или контекста (например, items: [...]).
  • Redux не диктует, как вы определяете редукторы. Это простые функции, которые возвращают следующее состояние с учетом текущего состояния и события (действия).
  • XState - это «редуктор с правилами» - вы определяете легальные переходы между конечными состояниями из-за событий, а также какие действия должны выполняться при переходе (или при входе / выходе из состояния)
  • Redux не имеет встроенного способа обработки побочных эффектов. Есть много вариантов сообщества, таких как redux-thunk, redux-saga и т. Д.
  • XState делает действия (побочные эффекты) декларативными и явными - они являются частью Stateобъекта, который возвращается при каждом переходе (текущее состояние + событие).
  • В настоящее время Redux не имеет возможности визуализировать переходы между состояниями, поскольку не различает конечное и бесконечное состояние.
  • XState имеет визуализатор: https://statecharts.github.io/xstate-viz, что возможно из-за декларативного характера.
  • Неявная логика / поведение, представленные в редукторах Redux, не могут быть сериализованы декларативно (например, в JSON)
  • Определения компьютеров XState, которые представляют логику / поведение, могут быть сериализованы в JSON и считаны из JSON. Это делает поведение очень переносимым и настраиваемым с помощью внешних инструментов.
  • Redux не является строго конечным автоматом.
  • XState строго придерживается спецификации W3C SCXML: https://www.w3.org/TR/scxml/
  • Redux полагается на разработчика, чтобы вручную предотвратить невозможные состояния.
  • XState использует диаграммы состояний для естественного определения границ для обработки событий, что предотвращает невозможные состояния и может быть проанализировано статически.
  • Redux поощряет использование единого, «глобального» атомного хранилища.
  • XState поощряет использование подхода, похожего на модель актера, когда может быть много иерархических экземпляров диаграммы состояний / «службы», которые взаимодействуют друг с другом.

На этой неделе я добавлю в документы больше ключевых отличий.

Дэвид Хуршид
источник
6
Наконец кто-то использует FSM и SCXML для предварительной разработки ... человек, вы спасли мне жизнь, я собираюсь изучить вашу библиотеку. Мне не нравится redux по некоторым причинам (во-первых, он путает термины событий и действий), а во-вторых, он «моделирует» сложные состояния с помощью миллионов флагов (подробных и неверных).
Карлос Вердес
1
@ Mike76 XState интегрируется с инструментами разработки Redux.
Дэвид Хоршид
Спасибо за подсказку, я разберусь с этим.
Mike76
1
Я попробовал XState + Redux DevTools. Он работает достаточно хорошо, но некоторые функции, похоже, отсутствуют. Например, XState + Redux DevTools не поддерживает такие функции, как «воспроизведение состояния», при котором воспроизводится последовательность предыдущих состояний. Это связано с ограничениями реализации?
Mike76
21

Конечный автомат не сообщает (заставляет) вас иметь однонаправленный поток данных. Это не имеет ничего общего с потоком данных. Это больше о сдерживающем изменении состояния и о переходах состояний . Итак, как правило, только некоторые части приложения могут быть разработаны с использованием конечных автоматов, только и только в том случае, если вам нужно ограничить / запретить некоторые изменения состояния и вы заинтересованы в переходах.

Помните, что с конечными автоматами, если по какой-либо причине (зависимость внешнего API и т. Д.) Есть вероятность, что приложение может быть заблокировано в состоянии, когда оно не может перейти в другое состояние из-за ограничений, вы должны решить эту проблему.

Но если вас интересует только последнее состояние приложения, а не переходы состояний , а ограничения состояния не имеют значения, тогда вам лучше не использовать конечный автомат и напрямую обновлять само состояние ( вы все равно можете обернуть состояние в обновлении класса Singleton через Классы действий ).


С другой стороны, Redux - это фреймворк однонаправленной архитектуры . Однонаправленные архитектуры заставляют вас иметь единственное направление потока данных. В Redux все начинается с User->View->(Action)->Store->Reducer->(Middleware)->Store->(State)->View. Как и State Machines, вы можете вызывать побочные эффекты с помощью промежуточного программного обеспечения в Redux. Вы можете ограничить / запретить переходы между состояниями, если хотите. В отличие от State Machine , Redux обеспечивает однонаправленный поток данных, в чистом виде ! функции редуктора, неизменяемые объекты состояния, единое наблюдаемое состояние приложения.

Джемшит Искендеров
источник