Зачем использовать Redux вместо Facebook Flux?

Я прочитал этот ответ , уменьшение шаблонного кода, просмотрела несколько примеров GitHub и даже немного попробовала redux ( приложения todo).

Насколько я понимаю, официальные мотивации редукции дают преимущества по сравнению с традиционными архитектурами MVC. НО это не дает ответа на вопрос:

Почему вы должны использовать Redux вместо Facebook Flux?

Это вопрос стилей программирования: функциональный или нефункциональный? Или вопрос в способностях/dev-инструментах, вытекающих из редукционного подхода? Может масштабирование? Или тестирование?

Прав ли я, если скажу, что redux — это поток для людей, перешедших с функциональных языков?

Чтобы ответить на этот вопрос, вы можете сравнить сложность реализации избыточных точек мотивации в Flux и Redux.

Вот пункты мотивации из мотивации официального документа Redux:

  1. Обработка оптимистичных обновлений (как я понимаю, это вряд ли зависит от 5-го пункта. Сложно ли это реализовать в facebook flux?)
  2. Рендеринг на сервере (facebook flux также может это делать. Есть ли преимущества по сравнению с redux?)
  3. Получение данных перед выполнением перехода по маршруту (Почему этого нельзя добиться в facebook flux? В чем преимущества?)
  4. Горячая перезагрузка (Это возможно с помощью React Hot Reload. Зачем нам избыточность ?)
  5. Функциональность отмены/возврата
  6. Любые другие моменты? Как постоянное состояние...

person VB_    schedule 08.09.2015    source источник
comment
Redux — это реализация Facebook Flux. Flux не является библиотекой или фреймворком. Это просто рекомендуемая архитектура для веб-приложений. Я не понимаю, как можно сравнивать конкретную реализацию с абстрактной концепцией, которая ее мотивировала. Фактическая реализация архитектуры Flux в Facebook — это Relay, а версия с открытым исходным кодом все еще находится на очень ранних стадиях. facebook.github.io/relay   -  person Charlie Martin    schedule 17.09.2015
comment
@CharlieMartin By FB Flux Я использую подобное приложение github.com/facebook/flux/tree/ мастер/примеры. Мой текущий проект написан на FB Flux (из-за FB Flux). Если вы хотите, вы можете думать об архитектуре Redux, а не о архитектуре FB Flux.   -  person VB_    schedule 17.09.2015
comment
Теперь я понимаю. Вы хотите сравнить пример реализации Flux в Facebook с реализацией Flux в Redux.   -  person Charlie Martin    schedule 17.09.2015
comment
Relay не является реализацией Flux — Relay/GraphQL больше занимается управлением выборкой/запросом данных с сервера, в то время как Flux в основном занимается структурированием потока данных между моделями данных на стороне клиента и компонентами представления. Однако есть некоторое совпадение: В Facebook у нас есть приложения, созданные полностью с использованием Flux, полностью с использованием Relay или с обоими. Один из шаблонов, который мы наблюдаем, заключается в том, что Relay позволяет управлять большей частью потока данных для приложения, но использует хранилища Flux на стороне для обработки подмножества состояния приложения   -  person Hal    schedule 23.09.2015


Ответы (8)


Автор Redux здесь!

Redux не намного отличается от Flux. В целом он имеет ту же архитектуру, но Redux может сократить некоторые углы сложности, используя функциональную композицию, где Flux использует регистрацию обратного вызова.

Принципиальной разницы в Redux нет, но я считаю, что некоторые абстракции проще или, по крайней мере, можно реализовать, которые было бы сложно или невозможно реализовать во Flux.

Состав редуктора

Возьмем, к примеру, пагинацию. Мой пример Flux + React Router обрабатывает разбивку на страницы, но код для этого ужасен. Одна из причин, по которой это ужасно, заключается в том, что Flux делает неестественным повторное использование функций в разных хранилищах. Если два хранилища должны обрабатывать разбиение на страницы в ответ на разные действия, они либо должны наследоваться от общего базового хранилища (плохо !, вы замыкаетесь на определенном дизайне, когда используете наследование), или вызываете внешнюю функцию из обработчика событий, которая должна каким-то образом работать с частным состоянием хранилища Flux. Все это грязно (хотя определенно в сфере возможного).

С другой стороны, в Redux нумерация страниц естественна благодаря составу редуктора. Это редюсеры, так что вы можете написать фабрика редукторов, которая генерирует редукторы разбиения на страницы, а затем используйте его в дереве редукторов. Ключ к тому, почему это так просто, заключается в том, что в Flux хранилища являются плоскими, а в Redux редукторы могут быть вложены через функциональную композицию, точно так же, как компоненты React могут быть вложены друг в друга.

Этот шаблон также включает замечательные функции, такие как отсутствие пользовательского кода отменить/повторить. Можете ли вы представить, что подключение Undo/Redo к приложению Flux состоит из двух строк кода? Едва. С Redux это так — опять же благодаря шаблону композиции редуктора. Я должен подчеркнуть, что в этом нет ничего нового — это шаблон, впервые созданный и подробно описанный в Elm Architecture. который сам находился под влиянием Flux.

Рендеринг сервера

Люди прекрасно выполняли рендеринг на сервере с помощью Flux, но, учитывая, что у нас есть 20 библиотек Flux, каждая из которых пытается сделать серверный рендеринг «более простым», возможно, у Flux есть некоторые шероховатости на сервере. Правда в том, что Facebook не занимается серверным рендерингом, поэтому они не очень беспокоятся об этом и полагаются на экосистему, чтобы упростить ее.

В традиционном Flux хранилища — это синглтоны. Это означает, что трудно разделить данные для разных запросов на сервере. Не невозможно, но тяжело. Вот почему большинство библиотек Flux (а также новые Flux Utils) теперь предлагаем вам использовать классы вместо синглтонов, чтобы вы могли создавать экземпляры хранилищ для каждого запроса.

Есть еще следующие проблемы, которые вам нужно решить в Flux (либо самостоятельно, либо с помощью вашей любимой библиотеки Flux, такой как Flummox или Alt):

  • Если магазины являются классами, как мне создавать и уничтожать их с помощью диспетчера по запросу? Когда я регистрирую магазины?
  • Как гидратировать данные из хранилищ, а затем повторно гидратировать их на клиенте? Нужно ли для этого реализовывать специальные методы?

По общему признанию, фреймворки Flux (не ванильный Flux) имеют решения этих проблем, но я нахожу их слишком сложными. Например, Flummox просит вас реализовать serialize() и deserialize() в ваших магазинах. Alt решает эту проблему лучше, предоставляя takeSnapshot(), который автоматически сериализует ваше состояние в дереве JSON.

Redux идет еще дальше: поскольку существует только одно хранилище (управляемое множеством редюсеров), вам не нужен какой-либо специальный API для управления (ре)гидратацией. Вам не нужно «сбрасывать » или «гидратные» магазины — есть только один магазин, и вы можете прочитать его текущее состояние или создать новый магазин с новым состоянием. Каждый запрос получает отдельный экземпляр хранилища. Подробнее о серверном рендеринге с помощью Redux.

Опять же, это тот случай, когда что-то возможно как в Flux, так и в Redux, но библиотеки Flux решают эту проблему, вводя массу API и соглашений, а Redux даже не нужно ее решать, потому что у него нет этой проблемы в первое место благодаря концептуальной простоте.

Опыт разработчиков

На самом деле я не собирался делать Redux популярной библиотекой Flux — я написал ее, когда работал над своим выступлением ReactEurope. на горячую перезагрузку с путешествием во времени. У меня была одна главная цель: сделать возможным изменение кода редуктора на лету или даже «изменить прошлое», вычеркивая действия, и видеть, как пересчитывается состояние.

Я не видел ни одной библиотеки Flux, способной это сделать. React Hot Loader также не позволяет вам это сделать — фактически он ломается, если вы редактируете хранилища Flux, потому что не знает, что с ними делать.

Когда Redux необходимо перезагрузить код редуктора, он вызывает replaceReducer(), а приложение работает с новым кодом. Во Flux данные и функции запутаны в хранилищах Flux, поэтому вы не можете «просто заменить функции». Более того, вам придется каким-то образом перерегистрировать новые версии в Dispatcher, чего в Redux даже нет.

Экосистема

Redux имеет богатую и быстрорастущую экосистему. Это связано с тем, что он предоставляет несколько точек расширения, таких как промежуточное ПО. Он был разработан с учетом таких вариантов использования, как логирование, поддержка Promises, Observables, маршрутизация, проверки разработчиков на неизменяемость, постоянство и т. д., имея в виду. Не все из них окажутся полезными, но приятно иметь доступ к набору инструментов, которые можно легко комбинировать для совместной работы.

Простота

Redux сохраняет все преимущества Flux (запись и воспроизведение действий, однонаправленный поток данных, зависимые мутации) и добавляет новые преимущества (легкая отмена-повтор, горячая перезагрузка) без внедрения Dispatcher и регистрации в магазине.

Сохранение простоты важно, потому что это помогает вам оставаться в здравом уме, пока вы реализуете абстракции более высокого уровня.

В отличие от большинства библиотек Flux, поверхность Redux API крошечная. Если вы удалите предупреждения разработчиков, комментарии и проверки работоспособности, это составит 99 строк. Нет сложного асинхронного кода для отладки.

Вы действительно можете прочитать его и понять весь Redux.


См. также мой ответ о недостатках использования Redux по сравнению с Flux.

person Dan Abramov    schedule 03.10.2015
comment
спасибо за ответ ... я новичок в js ... в своем ответе вы сказали, что поток использует шаблон проектирования singleton ... можете ли вы сказать мне в редуксе, какой шаблон проектирования они используют ... и в потоке может вы скажите мне, где они используют шаблон singleton... можете ли вы привести оба примера... Я понял, что делает шаблон проектирования отсюда одноэлементный - person ; 06.04.2016
comment
Я начал свою реализацию Android/Java (Fluxxan) на основе Fluxxor (в основном чистый поток). Как только я увидел редукс, я был продан. Есть некоторые части, которые я сохранил только в потоке, но, чувак, твоя библиотека потрясающая! - person frostymarvelous; 12.04.2016
comment
Хочешь изучить Redux? просто посмотрите это видео: youtube.com/watch?v=ucd5x3Ka3gw - person gsalgadotoledo; 19.09.2016
comment
Мы выбрали redux из-за того, что он более самоуверен, чем flux. Мы постоянно спорили о том, как/куда должен идти тот или иной код и т. д. Redux избавил нас от всей этой путаницы. Мы создали приложения с Redux для Интернета и React Native, и это потрясающе! - person SomethingOn; 13.12.2016
comment
Строка github.com/reactjs/ redux/blob/ был ответом на вопрос, который я искал неделю: как структурировать хранилище и редукторы, чтобы можно было обрабатывать несколько экземпляров многократно используемого компонента, используемого в другом контексте, без дублирования логики. Ответ вроде бы такой: используйте трехуровневое хранилище: 1-й уровень: имя компонента (разбивка на страницы), 2-й уровень: имя контейнера (stargazersByRepo), 3-й уровень: уникальный ключ/идентификатор контейнера (${login}/${name}). Большое спасибо! - person qbolec; 27.07.2017
comment
Я только что понял, что это не решает проблему полностью, так как требует, чтобы родительский контроллер знал свой уникальный идентификатор. Это может быть сложно. Например, если у пагинатора было много дочерних элементов типа PageButtonLink, которым также нужно отслеживать их состояние, то я не вижу, как организовать хранилище и редукторы, если только я каким-то образом не назначу уникальные идентификаторы для пагинаторов. Возможно, вам стоит github.com/MrEfrem/redux-fly? - person qbolec; 28.07.2017
comment
Посмотрите видео, на которые ссылается @gsalgadotoledo, самое простое объяснение! - person guru_florida; 20.06.2018
comment
Дэн, я немного изменил формулировку вашего ответа здесь, чтобы сделать его немного более ясным, можете ли вы убедиться, что я не понял вас неправильно и не изменил ваш смысл? - person temporary_user_name; 14.01.2019

В Quora кто-то говорит:

Во-первых, на React можно писать приложения без Flux.

Также эта визуальная диаграмма, которую я создал для быстрого просмотра обоих, возможно, быстрый ответ для людей, которые не хотят читать все объяснение: Flux против Redux< /а>

Но если вам все еще интересно узнать больше, читайте дальше.

Я считаю, что вы должны начать с чистого React, а затем изучить Redux и Flux. После того, как вы получите НАСТОЯЩИЙ опыт работы с React, вы увидите, полезен ли вам Redux или нет.

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

Если вы начнете непосредственно с Redux, вы можете получить перегруженный код, код, который сложнее поддерживать, и с еще большим количеством ошибок, чем без Redux.

Из документов Redux:

Мотивация
Поскольку требования к одностраничным приложениям JavaScript становятся все более сложными, наш код должен управлять большим количеством состояний, чем когда-либо прежде. Это состояние может включать ответы сервера и кэшированные данные, а также локально созданные данные, которые еще не были сохранены на сервере. Состояние пользовательского интерфейса также усложняется, так как нам нужно управлять активными маршрутами, выбранными вкладками, счетчиками, элементами управления разбиением на страницы и так далее.

Управлять этим постоянно меняющимся состоянием сложно. Если модель может обновлять другую модель, то представление может обновлять модель, которая обновляет другую модель, а это, в свою очередь, может привести к обновлению другого представления. В какой-то момент вы перестаете понимать, что происходит в вашем приложении, поскольку вы потеряли контроль над тем, когда, почему и как его состояние. Когда система непрозрачна и недетерминирована, трудно воспроизвести ошибки или добавить новые функции.

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

С этой сложностью трудно справиться, поскольку мы смешиваем два понятия, о которых человеческому разуму очень трудно рассуждать: мутация и асинхронность. Я называю их Mentos и Coke. Оба могут быть хороши по отдельности, но вместе они создают беспорядок. Такие библиотеки, как React, пытаются решить эту проблему на уровне представления, удаляя как асинхронность, так и прямые манипуляции с DOM. Однако управление состоянием ваших данных остается за вами. Здесь на помощь приходит Redux.

Следуя по стопам Flux, CQRS и Event Sourcing, Redux пытается сделать изменения состояния предсказуемыми, накладывая определенные ограничения на то, как и когда могут происходить обновления. Эти ограничения отражены в трех принципах Redux.

Также из документов Redux:

Основные концепции
Redux сам по себе очень прост.

Представьте, что состояние вашего приложения описывается как простой объект. Например, состояние приложения todo может выглядеть так:

{
  todos: [{
    text: 'Eat food',
    completed: true
  }, {
    text: 'Exercise',
    completed: false
  }],
  visibilityFilter: 'SHOW_COMPLETED'
}

Этот объект похож на «модель», за исключением того, что в нем нет сеттеров. Это делается для того, чтобы разные части кода не могли произвольно изменять состояние, вызывая трудновоспроизводимые ошибки.

Чтобы что-то изменить в состоянии, вам нужно отправить действие. Действие — это простой объект JavaScript (заметьте, мы не вводим никакой магии?), который описывает, что произошло. Вот несколько примеров действий:

{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }

Обеспечение того, чтобы каждое изменение описывалось как действие, позволяет нам иметь четкое представление о том, что происходит в приложении. Если что-то изменилось, мы знаем, почему это изменилось. Действия — это хлебные крошки того, что произошло. Наконец, чтобы связать состояние и действия вместе, мы пишем функцию, называемую редуктором. Опять же, в этом нет ничего волшебного — это просто функция, которая принимает состояние и действие в качестве аргументов и возвращает следующее состояние приложения. Было бы сложно написать такую ​​функцию для большого приложения, поэтому мы пишем более мелкие функции, управляющие частями состояния:

function visibilityFilter(state = 'SHOW_ALL', action) {
  if (action.type === 'SET_VISIBILITY_FILTER') {
    return action.filter;
  } else {
    return state;
  }
}

function todos(state = [], action) {
  switch (action.type) {
  case 'ADD_TODO':
    return state.concat([{ text: action.text, completed: false }]);
  case 'TOGGLE_TODO':
    return state.map((todo, index) =>
      action.index === index ?
        { text: todo.text, completed: !todo.completed } :
        todo
   )
  default:
    return state;
  }
}

И мы пишем еще один редюсер, который управляет полным состоянием нашего приложения, вызывая эти два редуктора для соответствующих ключей состояния:

function todoApp(state = {}, action) {
  return {
    todos: todos(state.todos, action),
    visibilityFilter: visibilityFilter(state.visibilityFilter, action)
  };
}

Это в основном вся идея Redux. Обратите внимание, что мы не использовали API-интерфейсы Redux. Он поставляется с несколькими утилитами для облегчения этого шаблона, но основная идея заключается в том, что вы описываете, как ваше состояние обновляется с течением времени в ответ на объекты действия, и 90% кода, который вы пишете, — это обычный JavaScript без использования Redux. себя, свои API или любую магию.

person Alireza    schedule 22.03.2017

Лучше всего начать с прочтения этого поста Дэна Абрамова, в котором он обсуждает различные реализации Flux и их компромиссы во время написания редукса: Эволюция Flux Frameworks

Во-вторых, на этой странице мотиваций, на которую вы ссылаетесь, на самом деле не столько обсуждаются мотивы Redux, сколько мотивы Flux (и React). Три принципа более специфичны для Redux, хотя по-прежнему не касаются отличий реализации от Стандартная архитектура Flux.

По сути, Flux имеет несколько хранилищ, которые вычисляют изменение состояния в ответ на взаимодействие UI/API с компонентами и транслируют эти изменения как события, на которые могут подписаться компоненты. В Redux есть только одно хранилище, на которое подписывается каждый компонент. IMO кажется, по крайней мере, что Redux еще больше упрощает и унифицирует поток данных, унифицируя (или уменьшая, как сказал бы Redux) поток данных обратно к компонентам, тогда как Flux концентрируется на унификации другой стороны потока данных - вид на модель.

person Hal    schedule 23.09.2015

Я один из первых пользователей и реализовал среднее одностраничное приложение с использованием библиотеки Facebook Flux.

Поскольку я немного опоздал с разговором, я просто укажу, что, несмотря на мои самые большие надежды, Facebook, похоже, считает свою реализацию Flux доказательством концепции, и она никогда не получала того внимания, которого заслуживает.

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

Мы решили, что в дальнейшем будем переходить на Redux, и я предлагаю вам сделать то же самое ;)

person Guy Nesher    schedule 05.01.2016
comment
Я разрабатываю приложение Facebook Flux шесть месяцев. И я до сих пор не уверен, стоит ли время миграции тех преимуществ, которые предоставляет Redux. Я буду очень признателен за все ваши комментарии о плюсах и минусах Redux по сравнению с FB flux! - person VB_; 11.01.2016
comment
@VolodymyrBakhmatiuk для нас это в основном сокращение количества шаблонов, которые мы должны написать + лучшая обработка ошибок (например, redux будет кричать, если вы запускаете действие, которое не было определено в вашем постоянном списке - поток FB не будет, и это может вызвать все такие проблемы) В потоке есть еще несколько расширенных возможностей, но я ими еще не пользовался - person Guy Nesher; 11.01.2016
comment
@GuyNesher, неопределенное действие должно обнаруживаться во время компиляции, а не во время выполнения. Flow (еще один вклад Facebook) позволяет вам сделать это. - person Dominique PERETTI; 09.02.2016
comment
@DominiquePERETTI - правда (также можно использовать линтинг), но это не меняет того факта, что не ловить ошибку во время выполнения довольно грустно. - person Guy Nesher; 11.02.2016
comment
Я написал несколько простых помощников для работы с FBFlux, и на самом деле он кажется менее шаблонным и настроенным приложением, чем все примеры приложений Redux, которые я нашел. Работал над приложением более 9 месяцев между двумя разработчиками и никогда не имел никаких проблем с архитектурой. - person rob2d; 22.03.2017

Вот простое объяснение Redux вместо Flux. В Redux нет диспетчера. Он опирается на чистые функции, называемые редюсерами. Ему не нужен диспетчер. Каждое действие обрабатывается одним или несколькими редюсерами для обновления одного хранилища. Поскольку данные неизменяемы, редукторы возвращают новое обновленное состояние, которое обновляет хранилищевведите здесь описание изображения

Для получения дополнительной информации Flux и Redux

person Prathap Kudupu    schedule 18.04.2017
comment
Что касается нескольких магазинов, теперь это можно сделать в Redux, в react-redux вы можете добавить ключ для изоляции магазинов: redux.js.org/faq/storesetup рабочий образец: github.com/Lemoncode/ редукс-несколько-магазинов - person Braulio; 30.09.2018

Я довольно долго работал с Flux и теперь довольно долго использую Redux. Как указал Дэн, обе архитектуры не так уж отличаются. Дело в том, что Redux делает вещи проще и чище. Помимо Flux, он учит вас нескольким вещам. Например, Flux — прекрасный пример однонаправленного потока данных. Разделение проблем, когда у нас есть данные, их манипуляции и слой представления. В Redux у нас то же самое, но мы также узнаем о неизменяемости и чистых функциях.

person Krasimir    schedule 25.01.2018

От нового сторонника реакции/редукции, мигрировавшего с (несколько лет) ExtJS в середине 2018 года:

После того, как я скатился вниз по кривой обучения избыточности, у меня возник тот же вопрос, и я подумал, что чистый поток будет проще, чем OP.

Вскоре я увидел преимущества Redux над Flux, как указано в ответах выше, и использовал его в своем первом приложении.

Снова разобравшись с шаблоном, я опробовал несколько других библиотек управления состоянием, лучшая из которых, которую я нашел, это матч-реванш.

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

Он также работает с теми же инструментами сокращения. Это хорошая статья, в которой рассказывается о некоторых преимуществах.

Так что для всех, кто пришел к этому сообщению SO в поисках «простого редукса», я рекомендую попробовать его как простую альтернативу редуксу со всеми преимуществами и 1/4 шаблона.

person egerardus    schedule 19.11.2018

Согласно этой статье: https://medium.freecodecamp.org/a-realworld-comparison-of-front-end-frameworks-with-benchmarks-2019-update-4be0d3c78075

Вам лучше использовать MobX для управления данными в вашем приложении, чтобы повысить производительность, а не Redux.

person yairniz    schedule 11.04.2019