React刮刮卡组件react-scratch-me实现onCompleted仅执行一次的定制求助
react-scratch-me组件onCompleted重复触发解决方案
你可以根据需求选择以下两种方案实现仅触发一次的效果:
方案一:调用侧添加触发锁(无需修改组件源码,推荐优先使用)
用useRef存储触发状态,避免重复执行,ref更新不会触发组件重渲染,性能开销极低,实现代码如下:import { useRef, useEffect } from 'react'; // 你的业务组件内部逻辑 const hasExecuted = useRef(false); const myFunction = () => { // 此处填写你原本的业务逻辑 console.log('刮卡完成触发') } const handleScratchComplete = () => { if (hasExecuted.current) return; myFunction(); hasExecuted.current = true; } // 若需要在组件重新渲染/刮卡重置时恢复可触发状态,添加以下重置逻辑 useEffect(() => { hasExecuted.current = false; }, [你的重置触发条件]) // 替换为你实际的重置依赖,比如刮卡ID、重置按钮状态等 // ScratchMe组件调用写法 <ScratchMe onCompleted={handleScratchComplete} completedAt={60} // 其余你原本配置的props保持不变 />方案二:修改react-scratch-me组件源码,从根源解决重复触发问题
给组件内部添加触发状态标记,避免每次刮动进度更新都重复触发回调,修改步骤如下:- 找到组件内计算刮开进度的逻辑段,一般在处理触摸/鼠标移动、计算canvas像素占比的函数中
- 组件内部新增ref存储触发状态:
const completedFired = useRef(false);- 修改原有的onCompleted触发判断逻辑:
// 原逻辑 // if (scratchPercentage >= completedAt) { // onCompleted?.(); // } // 修改后逻辑 if (scratchPercentage >= completedAt && !completedFired.current) { completedFired.current = true; onCompleted?.(); }- 添加状态重置逻辑,在组件重置、completedAt参数变更时重置标记:
useEffect(() => { completedFired.current = false; }, [completedAt, reset]) // reset替换为组件原有的重置props,没有的话可只保留completedAt
内容的提问来源于stack exchange,提问作者Jason Choi
相关产品推荐
相关产品推荐

