React中使用ref获取DOM节点总是返回null怎么办?
我在React组件里用useRef想获取一个div的宽度,但点击按钮时总报错说current是null。代码写成这样:
function BoxComponent() {
const boxRef = useRef(null);
const handleClick = () => {
console.log(boxRef.current.offsetWidth); // 这里报错
};
return (
<div>
<div ref="boxRef">内容区域</div>
<button onClick={handleClick}>测量宽度</button>
</div>
);
}
我明明给div加了ref=”boxRef”,但点击按钮时控制台显示boxRef.current是null。尝试过把ref初始化成new useRef(),也检查过组件是否渲染,但问题依旧。是不是因为用了函数组件?或者ref的写法哪里错了?
问题出在这一行:
正确做法是把ref属性的值改成你定义的ref对象,也就是boxRef本身,而不是字符串:
注意这里的关键是:
另外建议加上可选链操作符(?.),因为组件刚挂载时ref还没绑定好,或者DOM还没渲染完,直接访问offsetWidth会报错,用boxRef.current?.offsetWidth更安全。
还有一点,如果你在handleClick里马上调用,但ref指向的DOM是条件渲染的(比如在if里才显示),那确实可能拿不到,不过你这个例子看应该不是这个问题。
顺便吐槽一句,网上很多老教程还在教字符串ref,害人不浅,现在新项目里用字符串ref基本等于自找麻烦。
useRef返回的是个对象,你要把整个boxRef传给ref属性,不是传名字。另外初始化用 useRef(null) 是对的,别搞 new useRef() 这种不存在的东西。
还有就是,刚挂载的时候DOM可能还没生成,你得确保节点已经渲染出来了再访问。
改法很简单:
关键点就两个:一是 ref={boxRef} 要用花括号传引用,二是读之前判空。React会自动把DOM节点缓存到current里,只要节点渲染了就能拿到。
你之前写成 ref="boxRef",那只是个字符串属性,跟useRef完全没关系,current当然一直是null。