diff --git a/app/hooks/useUpdateEffect.ts b/app/hooks/useUpdateEffect.ts new file mode 100644 index 0000000..ba4e317 --- /dev/null +++ b/app/hooks/useUpdateEffect.ts @@ -0,0 +1,57 @@ +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); +} diff --git a/components/pages/work-flow/use-workflow-data.tsx b/components/pages/work-flow/use-workflow-data.tsx index 646c821..ac672ec 100644 --- a/components/pages/work-flow/use-workflow-data.tsx +++ b/components/pages/work-flow/use-workflow-data.tsx @@ -6,6 +6,7 @@ import { detailScriptEpisodeNew, getScriptTitle, getRunningStreamData, pauseMovi import { useAppDispatch, useAppSelector } from '@/lib/store/hooks'; import { setSketchCount, setVideoCount } from '@/lib/store/workflowSlice'; import { useScriptService } from "@/app/service/Interaction/ScriptService"; +import { useUpdateEffect } from '@/app/hooks/useUpdateEffect'; // 步骤映射 const STEP_MAP = { @@ -101,7 +102,7 @@ export function useWorkflowData() { applyScript } = useScriptService(); // 初始化剧本 - useEffect(() => { + useUpdateEffect(() => { if (currentStep !== '0') { console.log('开始初始化剧本', originalText,episodeId); // TODO 为什么一开始没项目id @@ -111,7 +112,7 @@ export function useWorkflowData() { mode.includes('auto') && applyScript(); }); } - }, [originalText]); + }, [originalText], {mode: 'none'}); // 监听剧本加载完毕 useEffect(() => { if (scriptBlocksMemo.length > 0) { @@ -121,13 +122,16 @@ export function useWorkflowData() { } }, [scriptBlocksMemo]); // 监听继续 请求更新数据 - useEffect(() => { + useUpdateEffect(() => { + if (currentStep === '6') { + return; + } if (isPauseWorkFlow) { pauseMovieProjectPlan({ project_id: episodeId }); } else { resumeMovieProjectPlan({ project_id: episodeId }); } - }, [isPauseWorkFlow]); + }, [isPauseWorkFlow], { mode: "debounce", delay: 1000 }); // 自动开始播放一轮 const autoPlaySketch = useCallback(() => {