Реагируйте на 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,
}
}
Почему просто добавление другой переменной вызывает эту проблему?
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
});
}