Redux-Thunk-создатели асинхронных действий обещают и цепочка не работает

Я пытаюсь отправить действие. Я нашел рабочие примеры для некоторых действий, но не такие сложные, как мои.

не могли бы вы дать мне подсказку? Что я делаю не так?

я использую TypeScript и недавно удалил все шрифты и максимально упростил свой код.

я использую redux-thunk и redux-promise, например:

import { save } from 'redux-localstorage-simple';
import thunkMiddleware from 'redux-thunk';
import promiseMiddleware from 'redux-promise';

const middlewares = [
        save(),
        thunkMiddleware,
        promiseMiddleware,
    ];
const store = createStore(
        rootReducer(appReducer),
        initialState,
        compose(
            applyMiddleware(...middlewares),
            window['__REDUX_DEVTOOLS_EXTENSION__'] ? window['__REDUX_DEVTOOLS_EXTENSION__']() : f => f,
        ),
    );

Компонент - Foo Компонент:

import actionFoo from 'js/actions/actionFoo';
import React, { Component } from 'react';
import { connect } from 'react-redux';

class Foo {
    constructor(props) {
        super(props);
        this._handleSubmit = this._handleSubmit.bind(this);
    }
    _handleSubmit(e) {
        e.preventDefault();
        this.props.doActionFoo().then(() => {
            // this.props.doActionFoo returns undefined
        });
    }
    render() {
        return <div onClick={this._handleSubmit}/>;
    }
}

const mapStateToProps = ({}) => ({});

const mapDispatchToProps = {
    doActionFoo: actionFoo,
};

export { Foo as PureComponent };
export default connect(mapStateToProps, mapDispatchToProps)(Foo);

действие - actionFoo:

export default () => authCall({
    types: ['REQUEST', 'SUCCESS', 'FAILURE'],
    endpoint: `/route/foo/bar`,
    method: 'POST',
    shouldFetch: state => true,
    body: {},
});

Действие - AuthCall:

// extremly simplified
export default (options) => (dispatch, getState) => dispatch(apiCall(options));

Действие-ApiCall:

export default (options) => (dispatch, getState) => {
    const { endpoint, shouldFetch, types } = options;

    if (shouldFetch && !shouldFetch(getState())) return Promise.resolve();

    let response;
    let payload;

    dispatch({
        type: types[0],
    });

    return fetch(endpoint, options)
        .then((res) => {
            response = res;
            return res.json();
        })
        .then((json) => {
            payload = json;

            if (response.ok) {
                return dispatch({
                    response,
                    type: types[1],
                });
            }
            return dispatch({
                response,
                type: types[2],
            });
        })
        .catch(err => dispatch({
            response,
            type: types[2],
        }));
};

2 ответов


С redux-thunk

Redux Thunk middleware позволяет писать создателей действий, которые возвращаются функция вместо действия

таким образом, это означает, что он не обрабатывает ваши обещания. Вы должны добавить redux-promise за обещание поддержки

экспорт по умолчанию является функцией промежуточного ПО. Если он получит обещание, он будет направлять решенную ценность обещания. Не будет отправка все, что угодно, если обещание отвергнет.

различия между redux-thunk vs redux-promise вы можете узнать здесь


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

import thunkMiddleware from 'redux-thunk';

const middlewares = [
        thunkMiddleware,
        // ANY OTHER MIDDLEWARE,
    ];
const store = createStore(
        rootReducer(appReducer),
        initialState,
        compose(
            applyMiddleware(...middlewares),
            window['__REDUX_DEVTOOLS_EXTENSION__'] ? window['__REDUX_DEVTOOLS_EXTENSION__']() : f => f,
        ),
    );