React中使用ref获取DOM节点总是返回null怎么办?

シ庆娇 阅读 55

我在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的写法哪里错了?

我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
诸葛玉惠
你这个问题其实不是React的问题,是ref的用法写错了,函数组件完全没问题。

问题出在这一行:
,你这里用的是字符串形式的ref,这是React早期的写法,早就废弃了,现在用字符串ref的话,React根本不会把它绑定到你的boxRef变量上,所以boxRef.current一直是null。

正确做法是把ref属性的值改成你定义的ref对象,也就是boxRef本身,而不是字符串:

function BoxComponent() {
const boxRef = useRef(null);

const handleClick = () => {
console.log(boxRef.current?.offsetWidth); // 加个可选链更稳妥
};

return (

内容区域



);
}


注意这里的关键是:
,花括号括起来,传的是那个ref对象本身,不是字符串。

另外建议加上可选链操作符(?.),因为组件刚挂载时ref还没绑定好,或者DOM还没渲染完,直接访问offsetWidth会报错,用boxRef.current?.offsetWidth更安全。

还有一点,如果你在handleClick里马上调用,但ref指向的DOM是条件渲染的(比如在if里才显示),那确实可能拿不到,不过你这个例子看应该不是这个问题。

顺便吐槽一句,网上很多老教程还在教字符串ref,害人不浅,现在新项目里用字符串ref基本等于自找麻烦。
点赞 5
2026-02-24 14:30
上官玲玲
你这个问题出在ref的写法上,根本没绑定成功。你写了 ref="boxRef",这是字符串形式,早就被废弃了,现在得用函数或useRef返回的对象。

useRef返回的是个对象,你要把整个boxRef传给ref属性,不是传名字。另外初始化用 useRef(null) 是对的,别搞 new useRef() 这种不存在的东西。

还有就是,刚挂载的时候DOM可能还没生成,你得确保节点已经渲染出来了再访问。

改法很简单:

function BoxComponent() {
const boxRef = useRef(null);

const handleClick = () => {
if (boxRef.current) {
console.log(boxRef.current.offsetWidth); // 现在能取到了
} else {
console.log('节点还没挂载');
}
};

return (

内容区域



);
}


关键点就两个:一是 ref={boxRef} 要用花括号传引用,二是读之前判空。React会自动把DOM节点缓存到current里,只要节点渲染了就能拿到。

你之前写成 ref="boxRef",那只是个字符串属性,跟useRef完全没关系,current当然一直是null。
点赞 9
2026-02-11 10:02