Redux Thunk - 异步,使用 Promises 链接操作

Redux Thunk - Async, chaining actions with Promises

所以最近两天我一直被这个问题难住了。

所以在应用程序中,有多个组织。我还有一个允许用户在组织之间切换的操作。

组织减速机:

import {
    FETCH_ORGANIZATION_LIST_REQUEST,
    FETCH_ORGANIZATION_LIST_SUCCESS,
    ORGANIZATION_ERROR,
    PICK_ORGANIZATION } from '../actions/types'

const INITIAL_STATE = { error: null,  organizations: [],  isFetching: false, currentOrganization: null, hasCurrentOrganization: false };

export default function (state = INITIAL_STATE, action) {
    switch (action.type){
        case FETCH_ORGANIZATION_LIST_REQUEST:
            return { ...state, isFetching: action.isFetching, error: null};
        case FETCH_ORGANIZATION_LIST_SUCCESS:
            return { ...state, isFetching: action.isFetching, organizations: action.payload, error: null };
        case ORGANIZATION_ERROR:
            return { ...state, isFetching: action.isFetching, error: action.payload };
        case PICK_ORGANIZATION:
            return { ...state, currentOrganization: action.organizationId, hasCurrentOrganization: action.hasCurrentOrganization };
        default:
            return state
    }
}

fetch组织和pick组织调用如下:

export function fetchOrganizationList() {
    const url = `/organizations`;

    return (dispatch) => getData(
        FETCH_ORGANIZATION_LIST_REQUEST,
        FETCH_ORGANIZATION_LIST_SUCCESS,
        ORGANIZATION_ERROR,
        true,
        url,
        dispatch);
};

export function pickOrganization(organizationId) {
    return (dispatch) => {
        dispatch({
            type: PICK_ORGANIZATION,
            organizationId: organizationId,
            hasCurrentOrganization: true
        })
    }
};

我有一个 getData 调用,它也用于其他服务器调用:

export function getData( actionRequest, actionSuccess, errorType, isAuthReq, url, dispatch) {
    const requestUrl = API_URL + url;
    let headers = {};

    dispatch({
        type: actionRequest,
        isFetching: true,
        error: null
    });

    if(isAuthReq) {
        headers = {headers: {'Authorization': 'Token ' + cookie.load('token')} }
    }

    axios.get(requestUrl, headers)
        .then((response) => {
            dispatch({
                type: actionSuccess,
                isFetching: false,
                payload: response.data
            });
            return response.data; 
        })
        .catch((error) => {
            errorHandler(dispatch, error, errorType)
        })

} 

最后我有一个 OrganizationSelector.jsx 容器组件,它允许我挑选当前组织。

import React, {
    Component,
    PropTypes,
} from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

import { fetchOrganizationList, pickOrganization, fetchAndPickCurrentOrganization } from '../../actions/organizations';

import Picker from '../../components/Picker';

class OrganizationSelector extends Component {


    componentDidMount() {

        this.props.fetchOrganizationList();
    }

    render() {
        const { isFetching, error, organizations, dispatch } = this.props;

        let count = !isFetching ? organizations.count : 1;

        return (
            <div>
                {isFetching && !error &&
                <li>Loading...</li>}
                {!isFetching && !error && count > 1 &&
                <Picker
                    currentOrganization={organizations.results[0].name}

                    options={organizations.results}
                    onSubmit={pickOrganization()}
                />
                }
                {!isFetching && !error && count === 1 &&
                <div>
                    {organizations.results[0].name}
                </div>
                }
            </div>
        );
    }
}

OrganizationSelector.propTypes = {};
OrganizationSelector.defaultProps = {};

const mapStateToProps = state => ({
    organizations: state.organization.organizations,
    isFetching: state.organization.isFetching,
    error: state.organization.error
});

function mapDispatchToProps(dispatch) {
    return {
        fetchOrganizationList: bindActionCreators(fetchOrganizationList, dispatch),
        // pickOrganization: bindActionCreators(pickOrganization, dispatch)
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(OrganizationSelector);

现在我遇到的问题是在同一个动作中将动作链接在一起 creator.I 想在 fetchOrganizationList 动作完成提取后传递 picOrganization 动作,我尝试做一些事情,通过 fetchListAndPickCurrentOrganization () 函数。

export function fetchListAndPickCurrentOrganization() {
    return (dispatch) => {
        dispatch(fetchOrganizationList())
            .then(response => {
                console.log(response) // This is where the Pick organization call will go
            })
            .catch(() => {
                console.log('error')
            })
    }
};

我也尝试直接在 fetchOrganizationList() 调用中进行 axios 调用,但我一直将 .then 视为未定义,我猜这是因为 axios 调用返回的响应没有传递到.然后.

我已经尝试了很多东西,但目标是 运行 在第一次安装应用程序时调用这两个调用,当然会再次使用 pickOrganization 调用在组织之间切换。

所以解决方案非常简单,我不得不 return axios.get 请求,因为它没有在我的初始解决方案中得到 returned,这就是为什么什么都没有传递给 .then,它是未定义的。

export function getData( actionRequest, actionSuccess, errorType, isAuthReq, url, dispatch) {
    const requestUrl = API_URL + url;
    let headers = {};

    dispatch({
        type: actionRequest,
        isFetching: true,
        error: null
    });

    if(isAuthReq) {
        headers = {headers: {'Authorization': 'Token ' + cookie.load('token')} }
    }

    return axios.get(requestUrl, headers)
        .then((response) => {
            dispatch({
                type: actionSuccess,
                isFetching: false,
                payload: response.data
            });
            return response.data; 
        })
        .catch((error) => {
            errorHandler(dispatch, error, errorType)
        })

} 

谢谢@Ashley 'CptLemming' Wilson 帮我解决了这个问题。