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

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

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

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

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

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

Ответы (3)

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

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

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

несколько моих пунктов ниже.

  • Состояние пользовательского интерфейса и бизнес-состояние / состояние серверной части объединены в redux. Из-за этого каждое обновление пользовательского интерфейса или бизнес-состояния создает обновление данных в хранилище redux.
  • Xstate разделяет состояние пользовательского интерфейса и состояние серверной части.
  • В redux все узлы находятся внутри корневого узла. Xstate децентрализует и распределяет данные внутри независимых машин.
  • Приложение может только переходить между уже определенными состояниями. Таким образом, любую ошибку или ошибку можно исправить в самой машине.
  • Внутренние состояния управляются самой Машиной в Xstate. Redux представляет новые состояния как флаги.
  • Агонист рендеринга - сохранение как можно большей части состояния в машинах, и, если нам нужно, мы можем относительно легко переключать фреймворки рендеринга (например, с реакции на vue).
  • Contexts предоставляет конкретный класс для представления единого интерфейса внешнему миру.

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

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

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


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

2022 WebDevInsider