import { useEffect, useRef, EffectCallback, DependencyList } from "react"; type Mode = "debounce" | "throttle" | "none"; interface Options { mode?: Mode; delay?: number; // 毫秒 } /** * useUpdateEffect - 统一版 * 1. 跳过首次执行 * 2. 可选防抖/节流 */ export function useUpdateEffect( effect: EffectCallback, deps: DependencyList, options: Options = { mode: "none", delay: 0 } ) { const { mode = "none", delay = 0 } = options; const isFirstRender = useRef(true); const timerRef = useRef | null>(null); const lastRunTimeRef = useRef(0); useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; return; } if (mode === "none" || delay <= 0) { return effect(); } if (mode === "debounce") { if (timerRef.current) clearTimeout(timerRef.current); timerRef.current = setTimeout(() => { effect(); }, delay); } if (mode === "throttle") { const now = Date.now(); if (now - lastRunTimeRef.current >= delay) { effect(); lastRunTimeRef.current = now; } } return () => { if (mode === "debounce" && timerRef.current) { clearTimeout(timerRef.current); } }; // eslint-disable-next-line react-hooks/exhaustive-deps }, deps); }