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

如何为自定义点击外部监听React Hook添加正确的TypeScript类型标注

问题1:ref类型不匹配报错修复

两处修改配合解决:

  • App组件中为useRef显式指定泛型,明确ref关联的元素类型:
// 把原来的 const asideRef = useRef(null); 替换为
const asideRef = useRef<HTMLElement>(null);
  • 调整useClick钩子的第一个入参类型,兼容ref初始为null的场景,同时使用更通用的RefObject类型(适配只读/可变两类ref):
// 把原来的 ref: React.MutableRefObject<HTMLElement> 替换为
ref: React.RefObject<HTMLElement | null>

问题2:事件监听器类型报错修复

该报错源于混淆了React合成事件与原生DOM事件的类型:你为checkClick参数标注的React.MouseEvent是React内部的合成事件类型,而document.addEventListener绑定的是原生DOM事件,对应的回调参数类型为原生MouseEvent。直接修改参数类型即可:

// 把原来的 const checkClick = (e: React.MouseEvent): void => { 替换为
const checkClick = (e: MouseEvent): void => {

完整修改后代码

App.tsx

import { useRef, useCallback } from "react";
import useClick from "./useClick";

export default function App() {
  const asideRef = useRef<HTMLElement>(null);

  const handleStuff = useCallback(() => {
    console.log("a click outside of the sidebar occurred.");
  }, []);

  useClick(asideRef, handleStuff);

  return (
    <div className="App">
      <aside ref={asideRef}>
        <nav>
          <ul></ul>
        </nav>
      </aside>
    </div>
  );
}

useClick.ts

import React, { useEffect } from "react";

const useClick = (ref: React.RefObject<HTMLElement | null>, cb: () => void) => {
  useEffect(() => {
    const checkClick = (e: MouseEvent): void => {
      if (ref.current && !ref.current.contains(e.target as Node)) {
        cb();
      }
    };

    document.addEventListener("click", checkClick);

    return () => {
      document.removeEventListener("click", checkClick);
    };
  }, [ref, cb]);
};

export default useClick;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 11:54:03