【问题标题】:How to add global loading/spin effect in axios interceptor for a React project如何在 axios 拦截器中为 React 项目添加全局加载/旋转效果
【发布时间】:2019-01-17 14:15:33
【问题描述】:

我在 React 项目中使用 axios 进行 API 调用,我想在我的 axios 拦截器中的 api 调用请求和响应之间全局添加加载或旋转效果,这是我的拦截器的代码。

import Axios from 'axios'

Axios.interceptors.request.use(function (config) {
  // spinning start to show
  const token = window.localStorage.token;
  if (token) {
     config.headers.Authorization = `token ${token}`
  }
  return config
}, function (error) {
  return Promise.reject(error);
});

Axios.interceptors.response.use(function (response) {
  // spinning hide
  return response;
}, function (error) {
  return Promise.reject(error);
});

【问题讨论】:

    标签: javascript reactjs axios interceptor


    【解决方案1】:

    也许您可以采用更简单的方法,在您的应用忙于通过 axios 加载数据时显示全屏加载消息?

    例如,您可以在代码/项目中添加以下内容,以便在 axio 请求期间在屏幕上显示全局“加载消息”:

    CSS:

    /* Define css class for global loading message to cover 
       screen during axios operations */
    
    .loading-indicator:before {
        content: '';
        background: #000000cc;
        position: fixed;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        z-index: 1000;
    }
    
    .loading-indicator:after {
        content: 'Loading';
        position: fixed;
        width: 100%;
        top: 50%;
        left: 0;
        z-index: 1001;
        color:white;
        text-align:center;
        font-weight:bold;
        font-size:1.5rem;        
    }
    

    Javascript:

    Axios.interceptors.request.use(function (config) {
    
      // spinning start to show
      // UPDATE: Add this code to show global loading indicator
      document.body.classList.add('loading-indicator');
    
      const token = window.localStorage.token;
      if (token) {
         config.headers.Authorization = `token ${token}`
      }
      return config
    }, function (error) {
      return Promise.reject(error);
    });
    
    Axios.interceptors.response.use(function (response) {
    
      // spinning hide
      // UPDATE: Add this code to hide global loading indicator
      document.body.classList.remove('loading-indicator');
    
      return response;
    }, function (error) {
      return Promise.reject(error);
    });
    

    使用此方法,您甚至可以使用 CSS3 动画将“加载”消息替换为动画微调器或类似的东西 - 希望这会有所帮助!

    【讨论】:

    • 我应该把它放在哪个文件中以便全局访问?
    • 对不起,我不明白你的问题
    • 在反应中,我应该将此代码放在 app.js 文件中或我刚开始反应的任何其他地方,所以请您描述一下,因为我想从一个地方访问每个组件。
    • 只需要将拦截器文件导入index.js文件即可。比如 import './interceptor'
    • @DacreDenny 并发请求呢?考虑将 2 个请求发送到服务器并显示加载程序。然后请求 1 的响应命中然后加载程序消失但尚未收到请求 2 的响应!
    【解决方案2】:

    您可以在更高级别的组件中设置 axios 拦截器,比如 App。您可以使用“SHOW_LOADER”和“HIDE_LOADER”操作类型在减速器中定义加载状态。这些拦截器将在通过 axios 发送和接收请求之前调度相应的操作,更新 store 中的加载状态,您可以通过它来渲染 Loader 组件。

    希望这能回答你的问题。

    应用组件

    import React from 'react';
    import axios from 'axios'
    import { connect } from 'react-redux';
    import { loading } from '../actions'
    import Loader from './Loader'
    
    class App extends React.Component{
     componentWillMount(){
       const self = this
       axios.interceptors.request.use(function (config) {
         // spinning start to show
         self.props.loading(true)
         return config
        }, function (error) {
          return Promise.reject(error);
        });
    
        axios.interceptors.response.use(function (response) {
         // spinning hide
          self.props.loading(false)
    
         return response;
       }, function (error) {
         return Promise.reject(error);
       });
     }
     render(){
       return (
        <div>
          { this.props.loader ? <Loader /> : null }
    
          {/* 
            Your other components
          */}
        </div>
       )
     }
    
    }
    
    const mapStateToProps = (state)=>{
      return {
        loader: state.loader
      }
    }
    
    export default connect(mapStateToProps,{
      loading
    })(App);
    

    装载机减速器

    const loader = (state = false, action) => {
        switch (action.type) {
            case "SHOW_LOADER":
                return action.data;
                break;
            case "HIDE_LOADER":
                return action.data;
                break;
            default:
                return state;
        }
    }
    
    export default loader;
    

    动作

    export const loading = (bool)=>{
      return bool ? {
        type:"SHOW_LOADER",
        data:bool
      }: {
        type: "HIDE_LOADER",
        data: bool
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-06
      • 2023-01-21
      • 2020-03-04
      • 1970-01-01
      • 2018-01-20
      • 1970-01-01
      • 2017-02-09
      相关资源
      最近更新 更多