Обновление поля isLoading в хранилище избыточности

У меня есть счетчик, который указывает, что мое приложение загружается. Многие редьюсеры в моем приложении должны иметь возможность установить для этого загрузчика значение true или false.

Мое предположение: это поле должно находиться на самом верхнем уровне дерева состояний. Назовем его isLoading.

Проблема: редукторы Redux обновляют свою часть дерева состояний. Каким образом я могу структурировать свои редукторы для обновления поля isLoading на самом верхнем уровне?

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

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

export const fetchAssets = () => {
  return dispatch => {
    request
      .get('http://myapi.com/assets')
      .set('Accept', 'application/json')
      .end(function(err, res){
        if (err) {
          return dispatch(fetchAssetsFailure(err));
        }
        dispatch(fetchAssetsSuccess(res.body.data));
      });
  }
}

person dipole_moment    schedule 15.11.2016    source источник


Ответы (1)


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

Пример создания действия:

const createSampleAction = (payload, isLoading) => ({
    type: 'SAMPLE_ACTION',
    payload,
    meta: {
        isLoading
    }
});

И редуктор:

const isLoadingReducer = (state = false, { meta }) => {
  const isLoading = meta && meta.isLoading;

  if (isLoading !== undefined) {
      return isLoading;
  }

  return state;
}

Если вас не устраивают редукторы, которые используют мета вместо типа действия, вы можете создать промежуточное ПО, которое будет выполнять то же свойство для отправки действий showLoading/hideLoading, и редюсер будет реагировать на эти действия:

const isLoadingMiddleware = ({ dispatch }) => next => {
  next(action);
  const isLoading = action.meta && action.meta.isLoading;

  if (isLoading !== undefined) {
      dispatch(isLoading ? showLoading () : hideLoading());
  }
}
person Ori Drori    schedule 15.11.2016