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

如何有条件调用自定义React Hook?useTimeout使用报错求助

问题解决:React useTimeout Hook 调用错误及状态控制

错误原因分析

  1. Hook调用规则违反:useTimeout作为自定义Hook,不能在useEffect这类回调函数内部调用,必须在组件或自定义Hook的顶层执行。
  2. 变量作用域问题:handleMouseEnter和handleMouseLeave是在useEffect内部定义的,组件顶层无法访问,导致JSX引用时找不到该变量。

解决方案

1. 调整组件内Hook调用位置

将useTimeout移到组件顶层调用,符合React Hook的调用规则,同时让返回的事件处理函数能被JSX直接访问。

2. 修改useTimeout Hook实现

让Hook内部监听open状态变化,自动控制定时器的启动与清理,同时实现鼠标进入/离开的暂停/重启逻辑。

完整代码示例

组件代码

import { useTimeout } from './useTimeout';

function YourComponent({ open, onCloseButtonClick, autoDismissDuration }) {
  // 组件顶层调用useTimeout,传入open状态
  const { handleMouseEnter, handleMouseLeave } = useTimeout(open, onCloseButtonClick, autoDismissDuration);

  return (
    <div onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
      {/* 组件内容 */}
    </div>
  );
}

自定义useTimeout Hook实现

import { useEffect, useRef } from 'react';

const useTimeout = (open, onClose, duration) => {
  const timeoutIdRef = useRef(null);

  // 启动自动关闭定时器
  const startTimeout = () => {
    if (!open) return;
    clearTimeout(timeoutIdRef.current);
    timeoutIdRef.current = setTimeout(onClose, duration);
  };

  // 清除定时器
  const clearTimeoutFn = () => {
    clearTimeout(timeoutIdRef.current);
    timeoutIdRef.current = null;
  };

  // 监听open、duration、onClose的变化,控制定时器
  useEffect(() => {
    if (open) {
      startTimeout();
    } else {
      clearTimeoutFn();
    }

    // 组件卸载时清理定时器
    return clearTimeoutFn;
  }, [open, duration, onClose]);

  // 鼠标进入:暂停自动关闭
  const handleMouseEnter = () => {
    clearTimeoutFn();
  };

  // 鼠标离开:恢复自动关闭
  const handleMouseLeave = () => {
    startTimeout();
  };

  return { handleMouseEnter, handleMouseLeave };
};

export default useTimeout;

逻辑说明

  • 当open变为true时,自动启动定时器,到达指定时长后触发onClose;当open变为false时,立即清除定时器。
  • 鼠标进入容器时,清除定时器,暂停自动关闭逻辑;鼠标离开时,重新启动定时器,恢复自动关闭。
  • 所有Hook调用都在组件或自定义Hook的顶层,完全符合React的Hook规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:53:32