Асинхронные действия разрешаются до получения результата выборки. - PullRequest
0 голосов
/ 11 октября 2018

Я использую 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()
    };
}

Redux Devtools action order

Есть идеи, что я здесь не так делаю?Если вам нужен дополнительный код или информация, пожалуйста, дайте мне знать.

...