React中useRef Hook何时将初始值替换为DOM节点?
React useRef 何时将初始值替换为DOM节点?
首先要明确:React 不会「替换」 useRef的初始值,而是在DOM节点挂载完成后,把DOM节点赋值给ref对象的current属性。
你遇到的问题核心是代码执行时机不对:
- 组件首次渲染时,useRef会创建一个包含你传入的初始值('1'、'2')的对象,这时候DOM还没挂载到页面上,React还没机会把DOM节点绑定到ref上。
- 你在组件函数体里直接写的
console.log(不管是第7行还是第15行),都是在渲染阶段执行的——这个阶段React还在计算要渲染什么,还没完成DOM的挂载和ref的赋值,所以current还是初始值。
ref的赋值动作发生在渲染周期的commit阶段后期:当React把计算好的DOM节点挂载到页面之后,才会把对应的DOM节点赋值给ref的current属性,这个时机晚于渲染阶段的代码执行,但早于useEffect的回调执行。
如果想拿到绑定了DOM节点的ref,有两种靠谱的方式:
- 用
useEffect:useEffect的回调会在DOM挂载/更新完成后触发,此时ref的current已经是对应的DOM节点了。 - 用回调式ref:把ref写成一个函数,比如
ref={(el) => { if(el) console.log('DOM节点:', el) }},当DOM节点挂载时,这个函数会被调用,参数就是对应的DOM节点,能直接拿到。
给你个验证用的示例代码:
import { useRef, useEffect } from 'react'; function App() { const refH1 = useRef('1'); const refP = useRef('2'); // 渲染阶段执行,此时ref还是初始值 console.log('渲染中:', refH1.current, refP.current); useEffect(() => { // DOM挂载完成后执行,此时ref已绑定DOM节点 console.log('DOM已挂载:', refH1.current, refP.current); }, []); return ( <div> <h1 ref={refH1}>Hello world</h1> <p ref={refP}>happy coding</p> </div> ); }
运行这段代码,你会看到「渲染中」输出初始值,「DOM已挂载」输出对应的DOM节点。
最后再梳理下关键结论:
- useRef的初始值只会在组件首次渲染时被设置一次,之后React不会主动修改它。
- DOM节点会在**组件完成DOM挂载(commit阶段后期)**后被赋值给ref的
current属性。 - 要获取绑定了DOM的ref,必须在DOM挂载完成后的时机去访问。
内容的提问来源于stack exchange,提问作者LeoPkm2-1
相关产品推荐
相关产品推荐

