Реагируйте на Redux, добавив дополнительное поле для действия, поэтому обещание будет возвращаться по-другому

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

export function getList() {
    const FIELD = '/comics'
    let searchUrl = ROOT_URL + FIELD + '?ts=' + TS + '&apikey=' + PUBLIC_KEY + '&hash=' + HASH;
    const request = axios.get(searchUrl)
    return {
        type: FETCH_LIST, 
        payload: request,
    }
}

и редуктор выглядит как

const INITIAL_STATE = { all: [], id: -1, isLoading: false };

export default function (state = INITIAL_STATE, action) {
    switch (action.type) {
        case FETCH_COMIC_LIST: 
            console.log('reducer action =', action, 'state =', state)
            return {
                ...state, 
                all: action.payload.data.data.results,
                isLoading: false
            }
        default:
            return state;
    }
}

Хороший результат

Как видите, объект возвращается нормально, и я могу получить свой список через action.payload.data.data.results

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

Как только я изменил свое действие на следующее и повторно запустил код, я получаю свою полезную нагрузку (как показано на рисунке ниже) как обещание, а не как возвращенный объект

export function getComicList() {
    const FIELD = '/comics'
    let searchUrl = ROOT_URL + FIELD + '?ts=' + TS + '&apikey=' + PUBLIC_KEY + '&hash=' + HASH;
    const request = axios.get(searchUrl)
    return {
        type: FETCH_COMIC_LIST, 
        isLoading: true, 
        payload: request,
    }
}

isLoading добавлено

Почему просто добавление другой переменной вызывает эту проблему?

3 ответа

Redux Promise и Redux Promise Middleware совместимы со стандартным действием Flux (FSA). Добавить meta ключ к действию и назначить ваши пары ключ / значение в нем.

Похожий вопрос / ответ: /questions/20349502/pochemu-redux-promise-vozvraschaet-nerazreshennoe-obeschanie-esli-ukazano-bolshe-chem-tip-i-parametryi-poleznoj-nagruzki/20349522#20349522

Из документации FSA:

Необязательное свойство meta МОЖЕТ быть значением любого типа. Он предназначен для любой дополнительной информации, которая не является частью полезной нагрузки.

Я думаю, что самый чистый и самый реактивный способ - это:

//types:
const FETCH_LIST_START = "…";
const FETCH_LIST_SUCCESS = "…";
const FETCH_LIST_ERROR = "…";

//action
const loadList = url => dispatch => {
  dispatch({type: FETCH_LIST_START });

  fetch(url)
    .then(res => {
      if (res.status !== 200) throw new Error('load failed');
      dispatch({ 
        type: FETCH_LIST_SUCCESS,
        payload : { res } }
      })

    )
    .catch(err => dispatch({ 
      type: FETCH_LIST_ERROR, 
      payload: { error } })
    );
};

//REDUCER
case: FETCH_LIST_START:
  return Object.assign({}, state, { isLoading: true });
  break;
case: FETCH_LIST_SUCCESS:
  return Object.assign({}, state, { 
     isLoading: false, 
     data: action.payload.res
  });
  break;
case FETCH_LIST_ERROR:
  …
  break;

Таким образом, предполагается, что вы используете Redux-Thunk. Основная идея состоит в том, чтобы ваш редуктор управлял состоянием, включая настройку isLoading Таким образом, вы можете обновить ваш компонент, пока изменяется состояние запроса... Приведенный выше код не готов к копированию / вставке, он предназначен для передачи идеи.

Попробуйте это - это то, как это делается с использованием redux-thunk - так что я надеюсь, что это похоже на redux-обещание-middleware. Также посмотрите, что возвращается из:

all: action.payload в твоем редукторе

    export function getList() {
        const FIELD = '/comics'
        let searchUrl = ROOT_URL + FIELD + '?ts=' + TS + '&apikey=' + PUBLIC_KEY + '&hash=' + HASH;

        // return a promise that the middleware should handle
        // return response or error from promise
        return axios.get(url)
          .then((response) => {
            type: FETCH_LIST,
            isLoading: true, 
            payload: response
          }).error((response) => {
            //handle error
          });
    }
Другие вопросы по тегам