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 /></>
}