Зачем использовать Redux поверх Facebook Flux? [закрыто]

1126

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

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

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

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

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

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

Вот побудительные мотивы от официальных побудительных мотивов :

  1. Обработка оптимистичных обновлений ( насколько я понимаю, это вряд ли зависит от 5-го пункта. Сложно ли реализовать это в Facebook Flux? )
  2. Рендеринг на сервере ( Facebook Flux также может сделать это. Есть ли преимущества по сравнению с Redx? )
  3. Извлечение данных перед выполнением переходов по маршрутам ( почему это невозможно сделать в Facebook Flux? В чем преимущества? )
  4. Горячая перезагрузка ( это возможно с React Hot Reload . Зачем нам нужен редукс? )
  5. Отменить / Повторить функциональность
  6. Какие-нибудь еще моменты? Как постоянное состояние ...
VB_
источник
73
Redux - это реализация «Facebook Flux». Flux - это не библиотека или фреймворк. Это просто рекомендуемая архитектура для веб-приложений. Я не понимаю, как можно сравнить конкретную реализацию с абстрактной концепцией, которая ее мотивировала. Реальная реализация Facebook архитектуры Flux - это Relay, а версия с открытым исходным кодом все еще находится на очень ранних стадиях. facebook.github.io/relay
Чарли Мартин
2
@CharlieMartin По заявке FB Flux я могу описать это следующим образом: github.com/facebook/flux/tree/master/examples . Мой текущий проект написан на FB Flux (из-за FB Flux). Если вы хотите, вы можете думать, как архитектура Redux над архитектурой FB Flux.
VB_
2
Теперь я понимаю. Вы хотите сравнить пример реализации Flux в Facebook с реализацией Flux в Redux
Чарли Мартин
13
Relay не является реализацией Flux - Relay / GraphQL больше занимается управлением извлечением / запросом данных на сервере, тогда как Flux главным образом занимается структурированием потока данных между моделями данных на стороне клиента и компонентами представления. Однако есть некоторые совпадения: в Facebook у нас есть приложения, созданные полностью с использованием Flux, полностью с использованием Relay или с обоими. Появляется один паттерн, позволяющий Relay управлять большей частью потока данных для приложения, но используя хранилища Flux на стороне для обработки подмножества состояния приложения
Hal

Ответы:

1958

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

Redux не что отличается от флюса. В целом он имеет ту же архитектуру, но 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 ) теперь предлагают использовать классы вместо синглетонов, чтобы можно было создавать экземпляры хранилищ по запросу.

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

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

По общему признанию, фреймворки Flux (не vanilla 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 .

Дан Абрамов
источник
3
спасибо за ответ ... я новичок в js .. в своем ответе вы сказали, что flux использует шаблон синглтон-дизайна ... можете ли вы мне сказать в редуксе, какой тип шаблона они используют ... и с помощью Flux Вы скажете мне, где они используют шаблон синглтона ...
2
Я начал свою реализацию Android / Java (Fluxxan) на основе Fluxxor (в основном чистый поток). Как только я увидел редукс, меня продали. Есть некоторые порции, которые я держал в чистом виде, но, чувак, твоя литература потрясающая!
морозный
5
Хочешь выучить Redux? просто посмотрите это
видео
5
Мы выбрали избыточность, потому что она более самоуверенная, чем флюс. Мы постоянно спорили о том, как / куда должен идти определенный код и т. Д. Redux убрал всю эту путаницу для нас. Мы создали приложения с редукцией для веб-сайтов и реагировать на них, и это потрясающе!
Что-то
1
Строка github.com/reactjs/redux/blob/… была ответом на вопрос, который я искал неделю: как структурировать хранилище и редукторы, чтобы можно было обрабатывать несколько экземпляров компонента многократного использования, используемого в разных контекстах, без дублирования логика. Кажется, что ответ таков: используйте глубокое хранилище трех уровней: 1-й уровень: имя компонента («разбиение на страницы»), 2-й уровень: имя контейнера («stargazersByRepo»), 3 уровень: уникальный ключ / идентификатор контейнера ( ${login}/${name}). Большое спасибо!
Qbolec
101

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

Прежде всего, полностью возможно написать приложения с React без Flux.

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

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

Я считаю, что вы должны начать с чистого React, а затем изучать Redux и Flux. После того, как у вас будет реальный опыт работы с React, вы увидите, полезен ли Redux для вас или нет.

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

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

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

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

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

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

С этой сложностью трудно справиться, поскольку мы смешиваем две концепции, которые человеческому разуму очень трудно рассуждать: мутация и асинхронность. Я называю их Ментос и Кола. Оба могут быть хороши, когда разделены, но вместе они создают беспорядок. Такие библиотеки, как 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, или любая магия.

Алиреза
источник
57

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

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

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

Хэл
источник
27

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

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

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

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

Гай Нешер
источник
Я занимаюсь разработкой приложения Facebook Flux в течение шести месяцев. И я до сих пор не уверен, стоит ли время миграции тех преимуществ, которые предоставляет Redux. Я буду очень признателен за ваши комментарии о плюсах и минусах Redux по сравнению с FB flux!
VB_
1
@VolodymyrBakhmatiuk для нас в основном сводится к уменьшению количества шаблонов, которые мы должны написать + лучшая обработка ошибок (например, при редуксе будет кричать, если вы запустите действие, которое не было определено в вашем константном списке - поток FB не будет, и это может вызвать все виды проблем) Есть несколько более продвинутых возможностей в потоке, но я еще не использовал их
Гай Нешер
1
@GuyNesher неопределенное действие должно быть обнаружено во время компиляции, а не во время выполнения. Flow (еще один вклад в Facebook) позволяет вам это сделать.
Доминик ПЕРЕТТИ
@DominiquePERETTI - правда (также можно использовать linting), но это не меняет того факта, что не отловить ошибку во время выполнения довольно печально
Гай Нешер
Я написал несколько простых помощников для работы с FBFlux, и на самом деле он выглядит менее стандартным и настраиваемым, чем все примеры приложений Redux, которые я нашел. Работал над приложением в течение 9+ месяцев между двумя разработчиками и никогда не имел проблем с архитектурой.
rob2d
20

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

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

Пратхап Кудупу
источник
Что касается нескольких магазинов, теперь в Redux есть что-то выполнимое, в Reaction-redux вы можете добавить ключ для изоляции магазинов: redux.js.org/faq/storesetup рабочий пример: github.com/Lemoncode/redux-multiple-stores
Braulio
6

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

Красимир
источник
5

От нового усыновителя реагирования / избыточности, переходящего с (несколько лет) ExtJS в середине 2018 года:

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

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

Получая контроль над плитой котла снова, я попробовал несколько других библиотек управления состоянием, лучшее, что я нашел, это реванш .

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

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

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

vanderwyst
источник