1. 代码封装
import React, { useState } from 'react';
import { Spin } from 'antd';
import './index.scss';// 自定义Hook useLoadings
export const useLoadings = () => {// 存储loading的状态,key是loading的唯一标识,value是loading的显示状态 const [loadings, setLoadings] = useState<Record<string, boolean>>({});const [keyMap, setKeyMap] = useState({});/*** @description 随机生成key* @param length * @returns { str }*/function generateRandomString(length: any) {const len: number = typeof length === 'number' && length > 0 ? length : 10;const characters: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()';let result: string = '';const charactersLength:number = characters.length;for (let i = 0; i < len; i++) {result += characters.charAt(Math.floor(Math.random() * charactersLength));}return result;}// 添加loading const addLoading = (tip: any): string => {let key:string; do { key = generateRandomString(10); } while (loadings[key]); // 当 loadings[key] 存在时继续循环 setKeyMap((pervKeyMap) => ({...pervKeyMap,[key]: tip}))setLoadings((prevLoadings) => ({...prevLoadings,[key]: true,}));return key;};// 移除指定的loading const closeLoading = (key: string) => {setKeyMap((pervKeyMap) => ({...pervKeyMap,[key]: ''}));setLoadings((prevLoadings) => ({...prevLoadings,[key]: false,}));};// 移除所有loading const clearAllLoadings = () => {setLoadings({});setKeyMap({});};// 渲染所有loading const LoadingIndicators = () => (<>{Object.keys(loadings).map((key) => (<Spin key={key} className='loading-ref' fullscreen spinning={loadings[key]} tip={keyMap[key]}/>))}</>);return {addLoading,closeLoading,clearAllLoadings,LoadingIndicators,};
};
index.scss优化样式防止抽屉z-index:1000
挡住
.loading-ref{z-index: 1001;
}
2. 实际使用
import { useLoadings } from './components/Loading';import { useEffect } from "react";export function DomC(){const { addLoading, closeLoading, clearAllLoadings, LoadingIndicators } = useLoadings();const clickNode = () => {const loading = addLoading('加载中...');setTimeout(() => {closeLoading(loading);}, 2000);}useEffect(() => {// return () => {clearAllLoadings();}}, []);return <><div onClick={clickNode}>按钮</div><LoadingIndicators /></>
}