如何修复React Hook中Ref的类型错误?
解决useFadeIn Hook的类型错误问题
问题原因
你的Hook中固定使用HTMLElement类型的ref,但React里<h2>、<p>、<ul>等元素对应的ref类型是更具体的子类型(比如HTMLHeadingElement、HTMLParagraphElement、HTMLUListElement),直接传递HTMLElement类型的ref会触发类型不兼容的错误。
解决方案:给Hook添加泛型支持
修改useFadeIn,让它支持泛型,适配不同类型的HTML元素:
import { useRef, useEffect, RefObject } from 'react'; export const useFadeIn = <T extends HTMLElement>(delay = 0): { ref: RefObject<T> } => { const elementRef = useRef<T>(null); useEffect(() => { const currentElement = elementRef.current; if (!currentElement) return; const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { setTimeout(() => { if (!currentElement) return; currentElement.classList.add('fade-in'); }, delay); } else { if (!currentElement) return; currentElement.classList.remove('fade-in'); } }, { rootMargin: '0px 0px -50% 0px' } ); observer.observe(currentElement); // 组件卸载时清理观察器,避免内存泄漏 return () => observer.unobserve(currentElement); }, [delay]); return { ref: elementRef }; };
组件中使用(无需额外修改,TS会自动推断类型)
"use client" import styles from "@components/Intro/Intro.module.scss" import { useFadeIn } from "@hooks/useFadeIn" const Intro = () => { // TS自动推断对应元素的类型 const fadeInTitle = useFadeIn(200); const fadeInIntro = useFadeIn(400); const fadeInSocial = useFadeIn(600); return ( <section className={styles.wrapper} > <h2 {...fadeInTitle}>Test</h2> <p {...fadeInIntro}>Test</p> <ul {...fadeInSocial} className={styles.socialLinks}> <li> <a href="#" target="_blank">Test</a> </li> </ul> </section> ) } export { Intro }
额外说明
- 泛型
<T extends HTMLElement>限制了参数必须是HTMLElement的子类型,确保类型安全。 - 添加了清理函数
return () => observer.unobserve(currentElement),避免组件卸载后观察器仍运行导致的内存泄漏。 - 也可以手动指定泛型类型,比如
const fadeInTitle = useFadeIn<HTMLHeadingElement>(200),不过TS的自动推断已经足够方便。
内容的提问来源于stack exchange,提问作者dev_el
相关产品推荐
相关产品推荐

