import React, { useEffect, useRef } from 'react' import ReactDOM from 'react-dom' import Nprogress from 'nprogress' import 'nprogress/nprogress.css' import ChaseLoading from '../ChaseLoading' import { Timeout } from 'ahooks/lib/useRequest/src/types' type ProcessLoadingProps = { show: () => void instance: HTMLElement | null hide: () => void parent: HTMLElement | Element | null } & React.FC<{ visible?: boolean spin?: boolean }> Nprogress.configure({ showSpinner: false }) // progress queue: singleton const queue: (Timeout | undefined)[] = [] const ProcessLoading: ProcessLoadingProps = props => { const { visible = false, spin = false } = props const timer = useRef() useEffect(() => { if (visible) { Nprogress.start() } else { Nprogress.done() } }, [visible]) /** for dynamicImport */ useEffect(() => { if (visible) { return () => {} } if (!queue.length) { timer.current = setTimeout(() => { Nprogress.start() }, 300) } queue.push(timer.current) return () => { requestAnimationFrame(() => { timer.current && clearTimeout(timer.current) queue.shift() if (!queue.length) { Nprogress.done() } }) } }, []) return spin ? (
) : null } ProcessLoading.instance = null ProcessLoading.parent = null ProcessLoading.show = function () { if (!ProcessLoading.instance) { ProcessLoading.instance = document.createElement('div') document.body.appendChild(ProcessLoading.instance) } ReactDOM.render(, ProcessLoading.instance) } ProcessLoading.hide = function () { const { instance } = ProcessLoading if (instance) { ReactDOM.render(, ProcessLoading.instance) } } const showPageLoading = ProcessLoading.show const destoryPageLoading = ProcessLoading.hide export default ProcessLoading export { showPageLoading, destoryPageLoading }