多个axios获得React-Redux请求

时间:2018-03-27 14:01:04

标签: reactjs redux axios

我有一个React-Redux应用程序,并希望使用axios进行并发API GET请求。我将url作为参数传递给动作。我怎样才能实现它?它是一个UI组件,当单击BU并单击BU时,它具有与API不同的数据。

enter image description here enter image description here

组件:

import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { getParallelData } from '../../actions/index';

class BUBGContainer extends Component {
  componentDidMount() {
    this.props.getParallelData('https://localhost:3001/reports/bu-list');
    this.props.getParallelData('https://localhost:3001/reports/bg-list');
  }

  updateTabs(i) {
    if (i === 1) {
      this.props.bgTab = true;
      this.props.buTab = false;
    } else {
      this.props.bgTab = false;
      this.props.buTab = true;
    }
  }


  render() {
    return (
      <div className="col-md-3">
        <label htmlFor="bu-bg-select">BU/BG:</label>
        <ul id="bu-bg-select-tabs" className="nav nav-tabs">
          <li role="presentation" className={ 'active' } onClick={ this.updateTabs(0) }><a>BU</a></li>
          <li role="presentation" className={ 'active' } onClick={ this.updateTabs(1) }><a>BG</a></li>
        </ul>
        <select name="bubgSelect" id="bu-bg-select" className="form-control">{_.map(this.props.items, (item, index) => <option key={ index }>{item}</option>)}</select>
        <p className="help-block">Hold <kbd>ctrl</kbd> and click to select multiple items</p>
      </div>
    );
  }
}

const mapStateToProps = state => ({
  items: state.bubgFetching.data.rows,
});

const mapDispatchToProps = dispatch => bindActionCreators({ getParallelData }, dispatch);

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

我不确定如何写一个动作来实现同样的目标。

我目前的行动是

export const getParallelData = url => (dispatch) => {
  dispatch(requestGetData());
  return axios.get(url)
    .then((response) => {
      dispatch(receiveGetData(response.data));
    })
    .catch((response) => {
      dispatch(receiveGetError(response.data));
    });
};

const requestGetData = () => ({ type: ACTION_TYPES.REQ_GET_DATA });

const receiveGetData = json => ({
  type: ACTION_TYPES.RECV_GET_DATA,
  data: json,
});

const receiveGetError = json => ({
  type: ACTION_TYPES.RECV_GET_ERROR,
  data: json,
});

我目前的减速机是

import _ from 'lodash';
import * as ACTION_TYPES from '../consts/action_types';

const initialState = {
  isLoading: false,
  data: [],
  error: false,
};

export const isFetchingGet = (state = initialState, action) => {
  const newState = _.cloneDeep(state);

  switch (action.type) {
    case ACTION_TYPES.RECV_GET_ERROR: {
      newState.isLoading = false;
      newState.data = action.data;
      newState.error = true;
      return newState;
    }

    case ACTION_TYPES.RECV_GET_DATA: {
      newState.isLoading = false;
      newState.data = action.data;
      newState.error = false;
      return newState;
    }

    case ACTION_TYPES.REQ_GET_DATA: {
      newState.isLoading = true;
      newState.error = false;
      return newState;
    }

    default:
      return state;
  }
};

这个link说明了如何使用它,但不知道如何实现它。

2 个答案:

答案 0 :(得分:2)

这是Promise.all的另一种选择,专注于您的并发请求问题。只是相关部分:

componentDidMount() {
    const list = [ "bu-list, "bg-list" ];
    this.props.getParallelData( list );
}

export const getParallelData = list =>
    async ( dispatch ) => {
        dispatch( requestGetData() );
        try {
            const promiseArray = list.map( el =>
                 axios.get( `https://localhost:3001/reports/${ el }` ) );
            const response = await Promise.all( promiseArray );
            return dispatch( receiveGetData( response ) );
            // and map through response for data, or
            // const [ buList, bgList ] = await Promise.all( promiseArray );
            // return dispatch( receiveGetData( [ buList.data, bgList.data ] ) );
            // or whatever form you want to pass receiveGetData
        } catch ( error ) {
            return dispatch( receiveGetError( error ) );
        }
 };

答案 1 :(得分:0)

您应该尝试使用redux-thunk或redux-saga中间件。 Thunk是更简单的选择。

https://github.com/gaearon/redux-thunk

你也可以使用async / await我发现它比promises更具可读性。

所以这是交易。您将发送函数而不是在您的动作创建者中发送对象,而redux-thunk会自动为您执行某些操作。

你会做这样的事情:

export const getParallelData = url => {
  return async dispatch => {
    const request = axios.get(url);
    try {
      if (response && response.ok) {
        await dispatch({
          type: ACTION_TYPES.REQ_GET_DATA,
          payload: request
        )}
      } catch(err) {
        await dispatch({
         type: ACTION_TYPES.REQ_GET_DATA,
         payload: err.toString()
        )}
      }
};

希望这有帮助!

相关问题