Redux FAQ: Настройка хранилища
Содержание
- Можно ли или нужно ли создавать несколько хранилищ? Можно ли импортировать хранилище напрямую и использовать его в компонентах?
- Можно ли иметь более одной цепочки мидлваров в расширителе хранилища? В чём разница между `next` и `dispatch` в функции мидлвара?
- Как подписаться только на часть состояния? Могу ли я получить диспатченое действие как часть подписки?
Настройка хранилища
Можно ли или нужно ли создавать несколько хранилищ? Можно ли импортировать хранилище напрямую и использовать его в компонентах?
Оригинальный паттерн Flux описывает наличие нескольких «хранилищ» в приложении, каждое из которых хранит разные области данных предметной области. Это может вызвать проблемы, такие как необходимость, чтобы одно хранилище «waitFor» другое хранилище для обновления. Это не требуется в Redux, так как разделение областей данных уже достигается путём разделения одного редьюсера на более мелкие редьюсеры.
Как и в случае с несколькими другими вопросами, возможно создать несколько отдельных хранилищ Redux на странице, но предпочтительный паттерн — это использование только одного хранилища. Наличие одного хранилища позволяет использовать Redux DevTools, упрощает сохранение и восстановление данных и упрощает логику подписки.
Некоторые веские причины использования нескольких хранилищ в Redux могут включать:
- Решение проблемы производительности, вызванной слишком частыми обновлениями некоторых частей состояния, подтвержденной профилированием приложения.
- Изоляция приложения Redux как компонента в более крупном приложении, в котором вы можете захотеть создать хранилище на каждый экземпляр корневого компонента.
Однако создание новых хранилищ не должно быть вашим первоначальным инстинктом, особенно если вы пришли из фона Flux. Попробуйте композицию редьюсеров в первую очередь, и используйте несколько хранилищ только в том случае, если это не решает вашу проблему.
Аналогично, хотя вы можете сослаться на ваш экземпляр хранилища, импортировав его напрямую, это не рекомендуемый паттерн в Redux. Если вы создаёте экземпляр хранилища и экспортируете его из модуля, он станет синглтоном. Это означает, что будет сложнее изолировать приложение Redux как компонент большего приложения, если это когда-нибудь понадобится, или включить рендеринг на сервере, потому что на сервере вы хотите создавать отдельные экземпляры хранилища для каждого запроса.
С React Redux, обертывающие классы, сгенерированные функцией connect(), на самом деле ищут props.store, если он существует, но лучше всего обернуть ваш корневой компонент в <Provider store={store}> и позволить React Redux позаботиться о передаче хранилища вниз. Таким образом, компоненты не должны беспокоиться об импорте модуля хранилища, и изоляция приложения Redux или включение серверного рендеринга гораздо проще в дальнейшем.
Дополнительная информация
Документация
Обсуждения
- #1346: Плохая ли практика просто иметь директорию «хранилища»?
- Stack Overflow: Redux несколько хранилищ, почему нет?
- Stack Overflow: Доступ к состоянию Redux в создателе действия
- Gist: Выход из парадигмы Redux для изоляции приложений
Можно ли иметь более одной цепочки мидлваров в расширителе хранилища? В чём разница между next и dispatch в функции мидлвара?
Мидлвары Redux ведут себя как связанный список. Каждая функция мидлвара может либо вызвать next(action) для передачи действия следующему мидлвару в очереди, вызвать dispatch(action) для перезапуска обработки в начале списка или вообще ничего не делать, чтобы остановить дальнейшую обработку действия.
Эта цепочка мидлваров определяется аргументами, переданными функции applyMiddleware при создании хранилища. Определение нескольких цепочек не будет работать правильно, так как у них будут отличающиеся ссылки dispatch и разные цепочки фактически будут разъединены.
Дополнительная информация
Документация
Обсуждения
- #1051: Недостатки текущего applyMiddleware и составления createStore
- Понимание Redux Middleware
- Исследование Redux Middleware
Как подписаться только на часть состояния? Могу ли я получить диспатченое действие как часть подписки?
Redux предоставляет единственный метод store.subscribe для уведомления слушателей о том, что хранилище обновилось. Обратные вызовы слушателей не получают текущее состояние в качестве аргумента — это просто указание на то, что что-то изменилось. Затем логика подписчика может вызвать getState() для получения текущего значения состояния.
Этот API предназначен как примитив низкого уровня без зависимостей или усложнений и может быть использован для построения логики подписки высокого уровня. UI-связывания, такие как React Redux, могут создавать подписку для каждого подключённого компонента. Также возможно написать функции, которые могут разумно сравнивать старое состояние с новым состоянием и выполнять дополнительную логику, если изменились определённые части. Примеры включают redux-watch, redux-subscribe и redux-subscriber, которые предлагают различные подходы к спецификации подписок и обработке изменений.
Новое состояние не передаётся слушателям для упрощения реализации расширителей хранилища, таких как Redux DevTools. Кроме того, подписчики должны реагировать на само значение состояния, а не на действие. Middleware может использоваться, если действие важно и требует специальной обработки.
Дополнительная информация
Документация
Обсуждения
- #303: API подписки со состоянием в качестве аргумента
- #580: Возможно ли получить действие и состояние в store.subscribe?
- #922: Предложение: добавить subscribe к API мидлвара
- #1057: Слушатель подписки может получить параметр действия?
- #1300: Redux великолепный, но отсутствует ключевая функция
Библиотеки
© 2015–2017 Dan Abramov
Licensed under the MIT License.
http://redux.js.org/docs/faq/StoreSetup.html