如何在自定义React hook中获取其调用方父组件的DOM元素ref
React自定义hook获取调用组件DOM元素的实现方案
React本身没有提供React.getParentRef()这类隐式获取调用方DOM的API,这是由React单向数据流的设计决定的:所有状态、引用的传递都需要显式声明,避免隐式依赖带来的维护问题。
你最初想到的「手动创建ref传入hook」的方案是完全符合官方规范的,也有更简洁的封装方式,两种常用实现如下:
方案1:组件侧创建ref传入hook
适合需要灵活控制绑定哪个DOM元素的场景:
import { useState, useEffect, useRef } from 'react'; // 自定义hook接收ref作为入参 const useExample = (targetRef) => { const [stateValue, setStateValue] = useState("example"); useEffect(() => { // 先判断ref是否绑定了DOM元素,避免空值报错 if (!targetRef.current) return; // 这里可以对DOM做任意操作,比如读取尺寸、绑定事件等 console.log('获取到的DOM元素:', targetRef.current); }, [targetRef]); return stateValue; }; // 调用hook的组件 const Component = () => { // 组件内创建对应DOM的ref const containerRef = useRef(null); // 把ref传入hook const data = useExample(containerRef); return ( <div ref={containerRef}> <span>{ data }</span> </div> ); };
方案2:hook返回ref给组件绑定
使用更简洁,无需组件侧提前创建ref:
import { useState, useEffect, useRef } from 'react'; const useExample = () => { // hook内部创建ref const targetRef = useRef(null); const [stateValue, setStateValue] = useState("example"); useEffect(() => { if (!targetRef.current) return; console.log('获取到的DOM元素:', targetRef.current); }, [targetRef]); // 把数据和ref一起返回,组件侧直接绑定即可 return { data: stateValue, bindRef: targetRef }; }; const Component = () => { const { data, bindRef } = useExample(); return ( <div ref={bindRef}> <span>{ data }</span> </div> ); };
注意事项
不要使用遍历DOM树查找父元素这类hack方案,这类实现会在React并发渲染、组件嵌套结构调整时出现不可预期的bug,显式传递ref是最稳定、可维护的实现方式。
内容的提问来源于stack exchange,提问作者Grover
相关产品推荐
相关产品推荐

