From 38c2ad7adab3b5397d5c409cbd1321c2a9033c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8C=97=E6=9E=B3?= <7854742+wang_rumeng@user.noreply.gitee.com> Date: Wed, 13 Aug 2025 20:00:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E7=9A=84useUpdateEffect=E9=92=A9=E5=AD=90=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=98=B2=E6=8A=96=E5=92=8C=E8=8A=82=E6=B5=81=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E5=B9=B6=E5=9C=A8useWorkflowData=E4=B8=AD?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E5=8E=9F=E6=9C=89useEffect=E4=BB=A5=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=89=A7=E6=9C=AC=E5=88=9D=E5=A7=8B=E5=8C=96=E5=92=8C?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=9B=B4=E6=96=B0=E9=80=BB=E8=BE=91=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/hooks/useUpdateEffect.ts | 57 +++++++++++++++++++ .../pages/work-flow/use-workflow-data.tsx | 12 ++-- 2 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 app/hooks/useUpdateEffect.ts 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(() => {