Redux - несколько магазинов, почему бы и нет?

Как примечание: я прочитал документы для Redux (тоже Baobab), и я сделал немалую долю в поиске и тестировании.

Почему так настоятельно рекомендуется, чтобы у приложения Redux был только один магазин?

Я понимаю плюсы и минусы настройки одного магазина по сравнению с настройкой нескольких магазинов (Есть много вопросов и ответов на SO по этому вопросу).

ИМО, это архитектурное решение принадлежит разработчикам приложений на основе потребностей их проектов. Так почему же это так настоятельно рекомендуется для Redux, почти до такой степени, что звучит обязательно (хотя ничто не мешает нам создавать несколько магазинов)?

РЕДАКТИРОВАТЬ: обратная связь после преобразования в один магазин

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

Несколько моментов, которые могут помочь другим понять, почему один магазин против многих является спорным вопросом во многих, многих случаях использования:

  • это надежно: мы используем селекторы, чтобы копаться в состоянии приложения и получать контекстную информацию. Мы знаем, что все необходимые данные находятся в одном магазине. Это позволяет избежать любых вопросов относительно того, где могут быть проблемы государства.
  • это быстро: в нашем магазине сейчас около 100 редукторов, если не больше. Даже при таком количестве данных лишь немногие редукторы обрабатывают данные в любой конкретной отправке, остальные просто возвращают предыдущее состояние. Аргумент о том, что огромный / сложный магазин (nbr редукторов) медленный, в значительной степени спорный. По крайней мере, мы не видели никаких проблем с производительностью.
  • дружественная отладка: хотя это наиболее убедительный аргумент в пользу использования избыточности в целом, он также подходит для одного хранилища против нескольких хранилищ. При создании приложения вы должны иметь ошибки состояния в процессе (ошибки программиста), это нормально. PITA - это когда отладка этих ошибок занимает несколько часов. Благодаря единственному хранилищу (и избыточному логгеру) мы никогда не тратили больше нескольких минут на любую проблему состояния.

несколько указателей

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

{
  apis: {     // data from various services
    api1: {},
    api2: {},
    ...
  }, 
  components: {} // UI state data for each widget, component, you name it 
  session: {} // session-specific information
}

Надеемся, что этот отзыв поможет другим.

РЕДАКТИРОВАТЬ 2 - полезные инструменты магазина

Для тех из вас, кому интересно, как "легко" управлять одним магазином, который может быстро стать сложным. Есть инструменты, которые помогают изолировать структурные зависимости / логику вашего магазина.

Существует Normalizr, который нормализует ваши данные на основе схемы. Затем он предоставляет интерфейс для работы с вашими данными и извлечения других частей ваших данных с помощью id, очень похоже на словарь.

Не зная Normalizr в то время, я строил что-то в том же духе. реляционный-json принимает схему и возвращает интерфейс на основе таблиц (немного похожий на базу данных). Преимущество реляционного json заключается в том, что ваша структура данных динамически ссылается на другие части ваших данных (посути, вы можете перемещаться по данным в любом направлении, как обычные объекты JS). Он не такой зрелый, как Normalizr, но я успешно использую его в производстве уже несколько месяцев.

7 ответов

Решение

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

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

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

  • Использование композиции редуктора упрощает реализацию "зависимых обновлений" waitFor в Flux, написав редуктор вручную, вызывая другие редукторы с дополнительной информацией и в определенном порядке.

  • С одним магазином очень легко сохраняться, увлажнять и читать состояние. Рендеринг сервера и предварительная выборка данных тривиальны, поскольку существует только одно хранилище данных, которое необходимо заполнить и повторно сгенерировать на клиенте, и JSON может описать его содержимое, не заботясь об идентификаторе или имени магазина.

  • Единый магазин делает возможными путешествия во времени Redux DevTools. Это также упрощает такие расширения сообщества, как redux-undo или redux-optimist, поскольку они работают на уровне редуктора. Такие "усилители-редукторы" не могут быть написаны для магазинов.

  • Одно хранилище гарантирует, что подписки вызываются только после обработки отправки. То есть к моменту уведомления слушателей состояние уже полностью обновлено. Во многих магазинах таких гарантий нет. Это одна из причин, по которой Flux нуждается в waitFor костыль. С одним магазином, это не проблема, которую вы видите в первую очередь.

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

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

Например, я склонен рассматривать следующие общие функциональные области как отдельные приложения:

  • Администратор
  • Аналитика / данные с панелей мониторинга
  • Управление биллингом и потоки покупок
  • Корпоративная учетная запись / управление разрешениями

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

Лучший способ управлять очень большими приложениями - это рассматривать их как композицию множества небольших приложений.

Если ваше приложение меньше, чем, скажем, ~50k LOC, вы, вероятно, должны игнорировать этот совет и следовать совету Дэна.

Если ваше приложение превышает 1 миллион LOC, вы, вероятно, должны разделять мини-приложения, даже если вы поддерживаете их в режиме моно репо.

Это архитектурное решение принадлежит разработчикам приложений на основе потребностей их проектов.

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

  • Это ненадежно, потому что части магазина не изолированы.
  • Это неэффективно, потому что вы клонируете и просматриваете хэш-три. Когда мутации растут арифметически - сложность растет геометрически. Вы не можете исправить это путем рефакторинга каких-либо редукторов, селекторов и т. Д. Вы должны разделить свою трия.
  • Когда это становится медленным, никто не хочет разделить это на отдельные приложения с отдельными магазинами. Никто не хочет тратить деньги на рефакторинг. Люди обычно конвертируют некоторые умные компоненты в дамп и все. Знаете ли вы, какое будущее ждет разработчиков излишков? Они будут поддерживать эти ады.
  • Это не дружественная отладка. Трудно отлаживать соединения между практически изолированными частями магазина. Очень сложно даже проанализировать количество этих связей.

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

Один неизменный магазин с однонаправленным потоком - не эликсир для каждой болезни. Если вы не хотите поддерживать архитектуру проекта, вы все равно будете страдать.

почему мы не можем использовать несколько магазинов с использованием RedEx????

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


Могу ли я создать несколько магазинов? Могу ли я импортировать свой магазин напрямую и самостоятельно использовать его в компонентах?

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

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

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

Некоторые допустимые причины использования нескольких магазинов в Redux могут включать:

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

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

официальный документ по редуксу

Несколько хранилищ могут быть полезны в следующих случаях использования 1. Если у вас есть большие компоненты, которые не зависят друг от друга с точки зрения структуры данных, поведения, контекста приложения. Изоляция этих компонентов облегчает управление вашими данными и потоком приложений. Это также помогает независимой разработке и обслуживанию ваших компонентов. 2. Проблемы с производительностью: не типичный вариант использования, но если некоторые из ваших компонентов обновляются очень часто и не влияют на другие компоненты, возможно, вы можете пойти в другие магазины.

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

Наличие одного магазина в Redux - это действительно то, что нам нужно во многих случаях, я использовал Redux и Flux и считаю, что Redux делает свою работу лучше!

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

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

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

Почему так настоятельно рекомендуется, чтобы приложение Redux имело только один магазин?

REDUX ИМЕЕТ 3 ОСНОВНЫХ ПРИНЦИПА:

1. Единый источник достоверности: «Все состояние приложения хранится в дереве объектов в одном хранилище».

2. Состояние доступно только для чтения: «Единственный способ изменить состояние — выполнить действие, описывающее произошедшее…».

3. Изменения вносятся с помощью чистых функций: «Редукторы пишутся как чистые функции, чтобы указать конкретный способ преобразования дерева состояний действием».

Так что если мы используем несколько хранилищ, то это тоже может нарушать ПРИНЦИП 1. Хотя можно использовать несколько REDUCERS, и в некоторых случаях это будет очень и очень полезно. Ниже приведены некоторые проблемы, которые могут возникнуть из-за нескольких магазинов.

  1. Трудно отлаживать.
  2. замедлить скорость.
  3. У него может быть несколько источников достоверности, поэтому он может вызвать несколько ошибок во время выполнения.

https://www.educative.io/courses/building-teslas-battery-range-calculator-with-react-and-redux/qVZRXlwQxv7

Другие вопросы по тегам