React条件渲染中forwardRef传递的ref无法取值的解决方法
解决条件渲染组件中forwardRef无法获取ref的问题
你的代码逻辑本身没有错误,问题出在ref的赋值时机和你访问ref的时机不匹配:
核心原因
React会在组件完成挂载(DOM更新完成)后,才会将目标DOM元素赋值给ref.current。而你在组件根级别直接console.log(ref),这行代码会在每次组件渲染时执行,包括:
- 初始渲染时,
list为空,Table组件未挂载,ref.current为null - 1秒后
list更新,组件重新渲染,此时Table组件开始渲染,但DOM还未完成更新,这时候打印的ref.current仍然是null;等到渲染完成、DOM更新后,React才会把DOM元素赋值给ref.current,但这时候你的console.log已经执行过了
正确的解决方案
通过useEffect监听条件渲染的触发状态(也就是list的变化),在组件挂载完成后再访问ref.current:
修改后的App组件代码
import { useEffect, useState, useRef } from "react"; import "./styles.css"; import Table from "./Table"; export default function App() { const [list, setList] = useState([]); const ref = useRef(null); useEffect(() => { setTimeout(() => { setList(["faraz"]); }, 1000); }, []); // 监听list的变化,当Table组件挂载后访问ref useEffect(() => { if (list.length > 0 && ref.current) { console.log("ref************", ref.current); // 这里可以进行需要操作DOM的逻辑 } }, [list]); return ( <div className="App"> <h1>Hello CodeSandbox</h1> <h2>Start editing to see some magic happen!</h2> {!!list.length && <Table ref={ref} />} </div> ); }
子组件代码保持不变
你的Table组件使用forwardRef的方式是正确的,已经正确将父组件传递的ref绑定到内部的div元素上,无需修改。
额外说明
- 如果需要在Table组件内部的DOM更新后执行逻辑,也可以在子组件中使用
useEffect,依赖绑定ref的DOM元素(或者直接监听组件挂载) - 不要在渲染阶段(比如组件根级别、JSX中)直接访问
ref.current,因为此时DOM可能还未准备好
内容的提问来源于stack exchange,提问作者Faraz
相关产品推荐
相关产品推荐

