首页 > 解决方案 > 一直等到所有 API 响应

问题描述

根据某些数据,我在我的一个 React 页面中多次调用单个 API。我面临的问题是添加一个等待加载程序,直到所有 API 都响应。我写了下面的代码。

return function (dispatch) {
    document.body.classList.add('loading');
    let appName = payload.appName;
    let functionName = payload.functionName;
    let tokenKey = payload.tokenKey;
    let url = host + "/focusRestApi/webapi/fetchModelList";
    let config = { headers: { 'Authorization': "token " + tokenKey, 'Token': localStorage.getItem('token') } };
    let data = {};
    data.applicationName = appName;
    url = url + "?portfolioId=" + portfolioName;
    if(functionName.length!=0){
    for(let i=0;i<functionName.length;i++){
    data.functionality = functionName[i].applicationFunctionalityName;
    axios.post(url, data, config)
      .then((response) => {
        dispatch({
          type: "FUNCTIONVIEW_CTD_DATA", payload:
            { functionName: functionName[i].applicationFunctionalityName, data: response.data }
        });
        if(i === functionName.length-1) {
          document.body.classList.remove('loading');
        }
      });
    }

  }
}

在这里,我在 If 条件中删除了加载程序。但它不能正常工作。在所有 API 响应之前,加载程序已被删除。我不确定这里有什么问题。有人可以帮我弄这个吗。提前致谢..

更新:上面的代码已经写在getGithubModals函数中。这是来自另一个 JS 文件的代码,我在其中调用上述函数:

if (props.functionality_data_list.length === 0) {
        props.dispatch(getGithubModals({
          appName: appId,
          functionName: "0", githubUser: git_user, repo: git_repo, tokenKey: git_token
        }));
      } else {
        props.functionality_data_list.forEach(function (id) {
          functionName.push(id);
          props.dispatch(getFunctionalityModals({
            applicationName: appId,
            functionality: id.applicationFunctionalityName
          }));
        });
        props.dispatch(getGithubModals({
          appName: appId,
          functionName: functionName, githubUser: git_user, repo: git_repo, tokenKey: git_token
        }));
      }

标签: reactjs

解决方案


以下示例将显示加载程序,直到完成 api 调用。

在动作文件中:

export const GET_SERVICE = '[SERVICE] GET LIST';
export const GET_SERVICE_SUCCESS = '[SERVICE] GET LIST SUCCESS';
export const GET_SERVICE_FAILURE = '[SERVICE] GET LIST FAILURE';

export function getService(options) {
    const request = axios.post('api/services', {options});
    return (dispatch) => {
        dispatch({
            type: GET_SERVICE
        });
        try {
            request.then((response) =>
                dispatch({
                    type: GET_SERVICE_SUCCESS,
                    payload: {data: response.data.data, meta: response.data.meta}
                })
            );
        } catch (e) {
            dispatch({
                type: GET_SERVICE_FAILURE
            });
        }
    }
}

在减速器文件中:

const initialState = {
    services: [],
    loading: false,
    hasErrors: false,
};

const serviceReducer = function (state = initialState, action) {
    switch (action.type) {
        case Actions.GET_SERVICE:
            return {...state, loading: true};
        case Actions.GET_SERVICE_SUCCESS:
            return {
                ...state,
                loading: false,
                services: [...action.payload.data],
                page: action.payload.meta.page,
                total: action.payload.meta.total
            };
        case Actions.GET_SERVICE_FAILURE:
            return {...state, loading: false, hasErrors: true};
        default:
            return state;
    }
};

export default serviceReducer;

您可以编写如下所示的加载器类:

import React from 'react'
import {ClipLoader} from "react-spinners";

const Loader = ({ loading, message }) => {

    return loading ? (
         <div className='wrapper'>
            <ClipLoader
               size={40}
               color={"#123abc"}
               loading={loading}
             />
             <span className='message'>
                {message}
             </span>
         </div>
    ) : null
};

export default Loader;

现在您可以在 App.js 中调用 getService 函数,如下所示:

import React from "react";
import ReactDOM from 'react-dom'
import * as ServiceActions from "./store/actions";
import Loader from "./Loader";
import MUIDataTable from "mui-datatables";

class App extends React.Component {

    state = {
        services: null
    };

    callApi = () => {
         this.setState(getService());
    };

    render() {
        return (
            <div>
                <button onClick={this.callApi}>Load Data</button>
                {loading ? <Loader css='margin-left: 48%; margin-top: 10%' loading={loading}/> :
                    <MUIDataTable
                        title={"Service List"}
                        data={services}
                        columns={columns}
                        options={options}
                    />
                }

            </div>
        );
    }
}

ReactDOM.render(<App/>, document.getElementById("root"));

export default App;

推荐阅读