如何为自定义点击外部监听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
相关产品推荐
相关产品推荐

