Добавление редукторов в промежуточное ПО из нескольких мест в Redux - PullRequest
0 голосов
/ 25 сентября 2019

Я создал проект с использованием Create React App, а затем добавил Redux.

Затем состояние избыточности разделяется на три части, каждая из которых имеет свой собственный редуктор и определенное промежуточное программное обеспечение.Редукторы размещаются в файлах, называемых part1.js part2.js part3.js, затем существует файл common.js, который импортирует редуктор и промежуточное программное обеспечение из part1-2-3.js и добавляет их в combineReducer и applyMiddeware.

У меня вопрос: есть ли необходимость не импортировать все в одном месте?То, что я хочу - это иметь возможность добавлять редуктор и промежуточное ПО к comineReducer и applyMiddleware из part1-2-3.js, причина в том, чтобы избавиться от явного стандартного файла стандартного кода в common.js.Это возможно или это единственный способ импортировать все в одно место?

ОБНОВЛЕНИЕ

Теперь у меня есть замечательные примеры того, как решить часть combineReducer, однакоМне все еще нужно сделать что-то подобное для applyMiddleware.Я нашел пример из следующего репо о том, как сделать что-то подобное с applyMiddleware.Однако он написан на TypeScript, и мне трудно перевести его на минимальный способ заставить это работать в приложении JS React / Redux.Было бы здорово с некоторыми примерами.

ОБНОВЛЕНИЕ

Так что я наконец нашел эту минимальную библиотеку, делающую то, что я хочу.

Ответы [ 2 ]

1 голос
/ 25 сентября 2019

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

используем store.replaceReducer https://redux.js.org/api/store#replacereducernextreducer

в configureStore (или любом файле, когда вы вызываете createStore из redux)

const store = createStore(/*...*/)
добавить
store.injectedReducers = {}; // Реестр редуктора

и создать новый файл с хуком injectReducer.

    const useInjectReducer reducer => {
      const store = useStore();
      const key = Object.keys(reducer)[0];
       if (
            Reflect.has(store.injectedReducers, key) &&
            store.injectedReducers[key] === reducer[key]
        ) {
            return;
        }

        store.injectedReducers = {
            ...store.injectedReducers,
            ...reducer
        };
        store.replaceReducer(combineReducers(store.injectedReducers));

    }

, и вы сможете использовать его в реакцииПриложение:

    export const TodoPage = () => {
        useInjectReducer({ [REDUCER_NAME]: TodoReducer });
        /*...*/
    }

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

 const dummyReducers = Object.keys(initialState).reduce((acc, current) => {
        acc[current] = (state = null) => state
        return acc;
    }, {});

и добавить это для:

const store = createStore(
    combineReducers(dummyReducers),
    initialState
) 

Мы используем тот же шаблон для Inject Sagas.

1 голос
/ 25 сентября 2019

Да!У меня есть реестр редукторов, который похож (почти идентичен) на этот менеджер редукторов: https://redux.js.org/recipes/code-splitting#using-a-reducer-manager:

const DEFAULT_REDUCER = state => state || null;

export class ReducerRegistry {
  constructor() {
    this._emitChange = null;

    this._reducers = {};
  }

  getReducers() {
    // default reducer so redux doesn't complain
    // if no reducers have been registered on startup
    if (!Object.keys(this._reducers).length) {
      return { __: { reducer: DEFAULT_REDUCER } };
    }

    return { ...this._reducers };
  }

  register(name, reducer, options = {}) {
    if (this._reducers.name && this._reducers.name !== reducer) {
      throw new Error(`${name} has already been registered`);
    }

    this._reducers = { ...this._reducers, [name]: { reducer, options } };
    if (this._emitChange) {
      this._emitChange(this.getReducers());
    }
  }

  setChangeListener(listener) {
    this._emitChange = listener;
  }
}

const reducerRegistry = new ReducerRegistry();
export default reducerRegistry;

Затем мои домены редукторов организованы в папки, похожие на стиль reducks: https://github.com/alexnm/re-ducks

В index.js домена reducks я импортирую реестр редуктора и регистрирую редуктор:

import Domain from './name';
import reducer from './reducer';

import { reducerRegistry } from '...wherever';
reducerRegistry.register(Domain, reducer); // register your reducer

export { ... whatever }

Наконец, мой store использует реестр редуктора следующим образом:

export const store = createStore(
  combine(reducerRegistry.getReducers()),
  initialState,
  composeEnhancers(applyMiddleware(...middlewares))
);

// Replace the reducer whenever a new reducer is registered (or unregistered).!!!!
// THIS IS THE MAGIC SAUCE!
reducerRegistry.setChangeListener(reducers =>
  store.replaceReducer(combine(reducers))
);

export default store;

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

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