React 、Axios、antd 封装全局Loading

1,066 阅读1分钟

前言

今天在做react要实现一个全局Loading效果,通常使用axios库与后端进行数据交互。为了更好的用户体验,在每次请求前添加一个加载效果,让用户知道在等待加载。

注意事项

直接在ts文件是不能使用antd的Spin,也不能使用createRoot,只能在tsx文件,所以封装文件如下

步骤

fullLoading.tsx文件

import { Spin } from 'antd';
import { createRoot } from 'react-dom/client';

const CONTAINER_ID = 'loading';
// 创建容器

function createContainer() {
  let container = document.getElementById(CONTAINER_ID);
  if (!container) {
    container = document.createElement('div');
    container.setAttribute('id', CONTAINER_ID);
    document.body.appendChild(container);
  }
  return container;
}

// 挂载dom
function renderLoading() {
  const container = createContainer();
  if (container) {
    const root = createRoot(container);
    root.render(<Spin spinning={true} fullscreen />);
  }
}

let requestCount = 0;
const fullLoading = {
  show: () => {
    // 显示loading
    if (requestCount === 0) {
      renderLoading();
    }
    requestCount++;
  },
  hide: () => {
    // 移除loading
    requestCount--;
    if (requestCount === 0) {
      const container = document.getElementById(CONTAINER_ID);
      container && document.body.removeChild(container);
    }
  }
};
export default fullLoading;

axios-instance.ts文件

import fullLoading from '@/components/fullLoading';
// 请求拦截器
axiosInstance.interceptors.request.use(
  config => {
    if (!config.data) {
      config.data = {};
    }
    if (config.headers.isLoading !== false) {
      fullLoading.show();
    }
    const token = tokenStorage.getItem();
    if (token) {
      config.headers.token = token;
    }
    return config;
     },
  error => {
    return Promise.reject(error);
  }
);
// 响应拦截器
axiosInstance.interceptors.response.use(
  (response: AxiosResponse) => {
    const { status, data } = response;
    if (response.config.headers.isLoading !== false) {
      fullLoading.hide();
    }
    if (status === 200) {
      return data;
    } else {
      return Promise.reject(data);
    }
   },
  error => {
    if (error.config.headers.isLoading !== false) {
      fullLoading.hide();
    }
    return Promise.reject(error);
  }
 );

接口调用

  post('api/update', params, { isLoading: false });