Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | import { useCallback, useEffect, useRef, useState } from 'react' import { useLatest } from 'react-use' export type UseIntervalResult<TResult> = [ TResult | undefined, { start: (delay?: number, duration?: number) => void stop: () => void }, ] /** * 以一定的间隔时间重复调用某函数,并返回调用结果。 * * @param callback 回调函数 * @param delay 间隔时间(毫秒),非数字时将不调用或停止调用函数 * @param duration 持续时间(毫秒) * @returns 返回调用结果 */ export function useInterval<TResult>( callback: () => TResult, delay: any, duration?: number, ): UseIntervalResult<TResult> { const [result, setResult] = useState<TResult>() const latestCallback = useLatest(callback) const latestDelay = useLatest(delay) const latestDuration = useLatest(duration) const interval = useRef<any>() const stop = useCallback(() => { if (interval.current) { clearInterval(interval.current) } }, []) const start = useCallback((delay?: number, duration?: number) => { stop() delay = delay ?? latestDelay.current duration = duration ?? latestDuration.current if (typeof delay === 'number') { setResult(latestCallback.current()) interval.current = setInterval(() => { setResult(latestCallback.current()) }, delay) } if (typeof duration === 'number') { setTimeout(() => { stop() }, duration) } }, []) useEffect(() => { start() return stop }, [delay]) return [result, { start, stop }] } |