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

寻求React中可重启的Timeout Hook实现方案

可重启的React定时器Hook实现方案

你的原Hook仅在delay参数变化时才会重新创建定时器,缺乏手动控制重启的能力,所以无法满足多次触发倒计时的需求。以下是修改后的可重启定时器Hook,以及针对图片tooltip场景的使用示例:

修改后的useTimeout Hook

import * as React from 'react';

/**
 * 支持重启和手动清除的React定时器Hook
 * @param {() => void} onTimerDone - 定时器到期后的回调函数
 * @param {number} delay - 延迟时间(毫秒)
 * @returns {{ reset: () => void, clear: () => void }} 控制定时器的方法
 */
export const useTimeout = (onTimerDone: () => void, delay: number) => {
  const timeoutRef = React.useRef<NodeJS.Timeout | null>(null);
  const savedCallback = React.useRef(onTimerDone);

  // 同步最新的回调函数
  React.useEffect(() => {
    savedCallback.current = onTimerDone;
  }, [onTimerDone]);

  // 清除当前活跃的定时器
  const clear = React.useCallback(() => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
      timeoutRef.current = null;
    }
  }, []);

  // 重启定时器:先清除现有定时器,再创建新的
  const reset = React.useCallback(() => {
    clear();
    timeoutRef.current = setTimeout(() => {
      savedCallback.current();
    }, delay);
  }, [delay, clear]);

  // 组件卸载时自动清理定时器
  React.useEffect(() => {
    return clear;
  }, [clear]);

  return { reset, clear };
};

核心改动说明

  • 新增clear方法:负责取消当前运行的定时器,避免内存泄漏或不必要的回调触发。
  • 新增reset方法:先调用clear终止现有定时器,再重新启动新的倒计时,实现按需重启。
  • 使用useCallback包裹方法:确保clear和reset的引用稳定,避免因渲染导致的依赖更新问题。
  • 组件卸载自动清理:通过useEffect的返回值,在组件销毁时自动清除定时器,防止内存泄漏。

图片Tooltip场景使用示例

const ImageWithTooltip = ({ src, tooltipText }) => {
  const [showTooltip, setShowTooltip] = React.useState(false);
  // 初始化定时器,延迟500ms显示tooltip
  const { reset, clear } = useTimeout(() => {
    setShowTooltip(true);
  }, 500);

  // 鼠标悬停时重启定时器
  const handleMouseEnter = () => {
    reset();
  };

  // 鼠标离开时取消定时器并隐藏tooltip
  const handleMouseLeave = () => {
    clear();
    setShowTooltip(false);
  };

  return (
    <div className="image-container" onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
      <img src={src} alt="展示图片" />
      {showTooltip && <div className="tooltip">{tooltipText}</div>}
    </div>
  );
};

场景逻辑说明

  • 鼠标首次悬停图片时,reset启动500ms倒计时,到期后显示tooltip。
  • 如果在倒计时结束前鼠标离开,clear会立即终止定时器,同时隐藏tooltip。
  • 若用户多次快速悬停离开,每次悬停都会通过reset重启倒计时,确保只有稳定悬停满500ms才会显示tooltip。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:00:58