Alfa Brain

Поддержка нескольких store в React-Redux приложении

Алексей ВечкановАлексей Вечканов   

Использование нескольких redux хранилищ в React приложении быть довольно сложным.

Изображение статьи

В приложении с React-Redux рекомендуется иметь только одно хранилище (один store). Но если по какой-то странной/особой причине вам нужно иметь более одного  store, вы столкнетесь с проблемами.

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

const Component1 = () => {
  return (
    <Provider store={store1}>
      <Provider store={store2}>
        <Component2 />
      </Provider>
    </Provider>
  );
};

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

Чтобы справиться с этой проблемой нам необходимо выполнить некоторые приготовления

Для этого нам понадобится react-redux 7 или выше. Поскольку версии ниже не используют Context API React. Мы будем использовать контексты для доступа к нескольким хранилищам без повторного использования провайдеров.

Создайте контекст для каждого store. Вы также можете импортировать ReactReduxContext из react-redux и использовать его для каждого из stor-ов, который вы хотите использовать в нужный момент.

const store1Context = React.createContext();
const store2Context = React.createContext();

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

<Provider store={store1} context={store1Context}>
  <Provider store={store2} context={store2Context}>
    <App/>
  </Provider>
</Provider>

Нам также нужно создать пользовательские dispatch хуки и selector хуки. Если вы используете хуки по умолчанию (useSelector, useDispatch), он будет использовать хранилище с контекстом по умолчанию, если таковой имеется.

import {
    createDispatchHook,
    createSelectorHook,
} from 'react-redux';

export const useStore1Dispatch = createDispatchHook(store1Context);
export const useStore1Selector = createSelectorHook(store1Context);

export const useStore2Dispatch = createDispatchHook(store2Context);
export const useStore2Selector = createSelectorHook(store2Context);

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

Если вы предпочитаете подключать store компонентом высшего порядка (HOC), вы можете сделать:

connect(mapStateToProps, mapDispatchtoProps,mergeProps, {context: store1Context})(Component) 

Это все. Если у вас будут вопросы, пожалуйста пишите комментарии. Спасибо.

За основу данной статьи, использована статья Handling multiple stores in a React-Redux application от автора Vikas Kumar



Поделиться: