You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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组件源码,从根源解决重复触发问题
    给组件内部添加触发状态标记,避免每次刮动进度更新都重复触发回调,修改步骤如下:

    1. 找到组件内计算刮开进度的逻辑段,一般在处理触摸/鼠标移动、计算canvas像素占比的函数中
    2. 组件内部新增ref存储触发状态:
    const completedFired = useRef(false);
    
    1. 修改原有的onCompleted触发判断逻辑:
    // 原逻辑
    // if (scratchPercentage >= completedAt) {
    //   onCompleted?.();
    // }
    
    // 修改后逻辑
    if (scratchPercentage >= completedAt && !completedFired.current) {
      completedFired.current = true;
      onCompleted?.();
    }
    
    1. 添加状态重置逻辑,在组件重置、completedAt参数变更时重置标记:
    useEffect(() => {
      completedFired.current = false;
    }, [completedAt, reset]) // reset替换为组件原有的重置props,没有的话可只保留completedAt
    

内容的提问来源于stack exchange,提问作者Jason Choi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 20:24:03