Я использую Redux с redux-thunk
для извлечения категорий из API.У меня есть действие с именем viewCategory
, которое зависит от наличия категорий в состоянии хранилища.
Я использовал пример получения сообщений Reddit с сайта Redux: https://redux.js.org/advanced/asyncactions#actions-js-asynchronous
Проблема, с которой я столкнулсяв том, что когда я звоню viewCategory
, обещание думает, что оно разрешено, когда отправляется REQUEST_CATEGORIES
, а не RECEIVE_CATEGORIES
.Поэтому, если зарегистрировать мое состояние в операторе then
, у меня будет пустой список категорий.
export function viewCategory(urlKey) {
return (dispatch, getState) => {
dispatch(fetchCategoriesIfNeeded()).then(() => {
let state = getState();
console.log(state); // should have categories
let categories = [...state.categories.mainCategories,
...state.categories.specialCategories];
let matchCategory = categories.find((category) => {
return category.custom_attributes.find(x => x.attribute_code === "url_key").value === urlKey;
});
dispatch({
type: Categories.VIEW_CATEGORY,
category: matchCategory
});
});
};
}
Функции, определяющие, следует ли выбирать категории вообще:
function shouldFetchCategories(state) {
const categories = state.categories;
if(categories.isFetching || categories.mainCategories.length > 0) {
return false;
} else {
return true;
}
}
export function fetchCategoriesIfNeeded() {
return (dispatch, getState) => {
if(shouldFetchCategories(getState())) {
return dispatch(fetchCategories());
} else {
return Promise.resolve();
}
};
}
функция, которая содержит фактический вызов выборки:
function fetchCategories() {
return (dispatch, getState) => {
dispatch(requestCategories());
const {locale} = getState().settings;
return fetch(`${BASE_URL}/categories/list`, {
method: "POST",
headers: {
"Accept-Language": locale
},
body: "Not interesting for stackoverflow"
})
.then(response => response.json())
.then(json => {
if(json !== undefined && json.items){
dispatch(receiveCategories(json.items));
}
});
};
}
Функции, в которые я отправляю типы REQUEST_CATEGORIES
& RECEIVE_CATEGORIES
:
function requestCategories() {
return {
type: Categories.REQUEST_CATEGORIES
};
}
function receiveCategories(result) {
const mainCategories = result.filter(category => category.level === 2);
const subCategories = result.filter(category => category.level === 3);
const categories = mainCategories.map(category => {
let children = subCategories.filter(x => x.parent_id === category.id);
return {
...category,
children
};
});
let specialCategories = categories.splice(categories.length - 2, 2);
return {
type: Categories.RECEIVE_CATEGORIES,
categories: categories,
specialCategories: specialCategories,
receivedAt: Date.now()
};
}
Есть идеи, что я здесь не так делаю?Если вам нужен дополнительный код или информация, пожалуйста, дайте мне знать.