前言
今天在做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 });