preloadedState при введении asyncReducers - PullRequest
0 голосов
/ 12 декабря 2018

Как можно иметь как preloadedState (гидратирующийся с сервера), так и динамически вводить редукторы?

In react-boilerplate или Как динамически загружать редукторы для разделения кода в приложении Redux? существует концепция редукторов, которые добавляются динамически в зависимости от просматриваемой страницы / компонентов.Извлечение из reducers.js:

export default function createReducer(asyncReducers) {
  return combineReducers({
    users,
    posts,
    ...asyncReducers
  });
}

Хотя это хорошо работает при переходе от одной страницы к другой (или только в клиентском приложении);при гидратации данных с сервера я сталкиваюсь с этой ошибкой:

Unexpected property "comments" found in previous state received by the reducer. Expected to find one of the known reducer property names instead: "users", "posts". Unexpected properties will be ignored.

(где comments - имя свойства динамически впрыскиваемого редуктора)

Причинаэта ошибка очевидна, поскольку preloadedState, поступающий с сервера (использующий React SSR), уже содержит comments, а первоначальный редуктор - нет, поскольку впоследствии он добавляется динамически.Ошибка исчезнет, ​​если я добавлю comments к своему combineReducers;однако это означает, что при инициализации приложения мне нужно включить все редукторы;что не идеально.

1 Ответ

0 голосов
/ 12 декабря 2018

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

{ comments: (state = null) => state }

Это также можно сделать автоматически, в зависимости от вашей реализации, так какза http://nicolasgallagher.com/redux-modules-and-code-splitting/

// Preserve initial state for not-yet-loaded reducers
const combine = (reducers) => {
  const reducerNames = Object.keys(reducers);
  Object.keys(initialState).forEach(item => {
    if (reducerNames.indexOf(item) === -1) {
      reducers[item] = (state = null) => state;
    }
  });
  return combineReducers(reducers);
};
...