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

多次触发setTimeout时如何覆盖前序定时器实现视频控件3秒后自动隐藏

问题修复方案

核心问题原因

  • 你声明的timeoutID是普通局部变量,组件每次重新渲染都会被重置,之前保存的定时器ID会丢失,导致clearTimeout无法正确清除上一次的定时器
  • 整体逻辑过于冗余,额外引入的secondCall状态和多组Promise异步逻辑会打乱执行顺序,且React的setState本身是异步更新的,依赖状态判断的逻辑容易出现时序错误
  • 没有处理组件卸载时的定时器清除逻辑,可能引发内存泄漏

修复方案

直接用useRef存储定时器ID,简化为标准的防抖重置逻辑即可,每次触发交互时先清空旧定时器,再开启新的3秒倒计时:

import { useRef, useState, useEffect } from 'react';
// 其他原有导入保持不变

const YourComponent = () => {
  const [showVideoControls, setShowVideoControls] = useState(false);
  // 用useRef存储定时器ID,组件全渲染周期内值持久化不会丢失
  const timerRef = useRef(null);

  // 点击交互的统一处理函数
  const handleControlTrigger = () => {
    // 第一步:清除上一次的定时器,重置倒计时
    if (timerRef.current) {
      clearTimeout(timerRef.current);
    }

    // 切换控件显隐:如果原本隐藏就显示,已经显示的场景可根据需求选择直接隐藏/保持显示重置倒计时
    if (!showVideoControls) {
      setShowVideoControls(true);
    } 
    // 如果需要点击已显示的控件直接隐藏,放开下面的注释即可
    // else {
    //   setShowVideoControls(false);
    //   return;
    // }

    // 开启新的3秒倒计时,到期自动隐藏控件
    timerRef.current = setTimeout(() => {
      setShowVideoControls(false);
    }, 3000);
  };

  // 组件卸载时清除残留定时器,避免内存泄漏
  useEffect(() => {
    return () => {
      if (timerRef.current) {
        clearTimeout(timerRef.current);
      }
    };
  }, []);

  return (
    <View style={{ width: '100%', height: '100%' }}>
      <TouchableWithoutFeedback onPress={handleControlTrigger}>
        <Text style={{ flex: 1 }}>{''}</Text>
      </TouchableWithoutFeedback>
      {/* 原有视频控件代码根据showVideoControls控制显隐即可 */}
    </View>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 17:24:08