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

React Native定时器结束后onTimerFinish函数未触发问题求助

问题原因及修复方案

核心问题:闭包陷阱导致无法获取最新时间差

你的代码里,useEffect的依赖数组是空的,这意味着里面的setInterval回调只会捕获组件初始渲染时的timeBetween值,后续currentTime更新时,回调里的timeBetween不会跟着变化,自然无法正确判断倒计时是否结束。另外,你在回调里先检查timeBetween再更新currentTime,逻辑顺序也反了,而且没做防重复触发的处理。


修复后的完整代码

import { useState, useEffect } from 'react';

const MyCountdownTimer = (props) => {
    const targetTime = new Date(props.targetDate).getTime();
    const [currentTime, setCurrentTime] = useState(Date.now());

    // 计算实时时间差
    const timeBetween = targetTime - currentTime;

    const days = Math.floor(timeBetween / (1000 * 60 * 60 * 24));
    const hours = Math.floor((timeBetween % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    const minutes = Math.floor((timeBetween % (1000 * 60 * 60)) / (1000 * 60));
    const seconds = Math.floor((timeBetween % (1000 * 60)) / 1000);

    useEffect(() => {
        // 先判断初始状态是否已经超时
        if (timeBetween < 0) {
            props.onTimerFinish();
            return;
        }

        const interval = setInterval(() => {
            const newCurrentTime = Date.now();
            const newTimeBetween = targetTime - newCurrentTime;
            
            // 更新当前时间
            setCurrentTime(newCurrentTime);

            // 检查是否超时,且只触发一次
            if (newTimeBetween < 0) {
                props.onTimerFinish();
                clearInterval(interval); // 触发后立即清除定时器
            }
        }, 1000);

        return () => clearInterval(interval);
    }, [props.targetDate, props.onTimerFinish]); // 加入依赖,确保回调能获取最新的props和时间相关值

    // UI渲染部分,根据需求用View包裹展示即可
    return (
        <div>
            <span>{days}天</span>
            <span>{hours}时</span>
            <span>{minutes}分</span>
            <span>{seconds}秒</span>
        </div>
    );
};

export default MyCountdownTimer;

关键修复点说明

  • 解决闭包问题:在setInterval回调里直接计算最新的newTimeBetween,不依赖外部的timeBetween变量;同时给useEffect添加正确的依赖项,确保组件能响应props变化。
  • 逻辑顺序调整:先更新currentTime,再判断时间差是否小于0,保证判断的是最新状态。
  • 防重复触发:触发onTimerFinish后立即清除定时器,避免重复调用回调。
  • 初始状态检查:组件挂载时先判断是否已经超时,避免错过触发时机。

内容的提问来源于stack exchange,提问作者Chaudhry Talha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:00:59