首页 > 解决方案 > 如何使用 React.useRef 获取实际的 Dom 节点?Element.getBoundingClientRect() 不适用于 useRef 变量

问题描述

我正在尝试使用 Element.getBoundingClientRect() 来获取 dom 元素的 x、y、top、left 值。

const editorRef = useRef() 
... // attatched editor ref on the dom element that I'm interested
... 
editorRef.current.focus() // works well 
const editorNodeRect = editorRef.current.getBoundingClientRect() // got error saying getBoundingClientRect() is not a function 

所以我通过查询选择节点来尝试这种方式

const editorNodebyQuery =document.querySelectorAll(".DraftEditor-root")[0];
const editorNodebyQueryRect = editorNodebyQuery.getBoundingClientRect() // work well!! 

但我不喜欢通过查询访问dom节点。我认为它很重。我想使用useRef。

第一个 rootEditorNode 是我通过 querySelector 得到的,它有 getBoundingClientRect() 函数第二个 editorRef.current 是我通过 useRef 得到的,它没有 getBoundingClientRect() 函数。

在此处输入图像描述

我只想知道如何将 getBoundingClientRect() 函数与 useRef() 一起使用

标签: javascriptreactjsdomreact-hooks

解决方案


很可能您的 editorRef 指向的是 React 组件,而不是 DOM 元素。你可以得到这样的元素

var element=ReactDOM.findDOMNode(editorRef.current);
var rect =element.getBoundingClientRect();

但是 ReactDOM.findDOMNode 在严格模式下被弃用(推荐使用)

<React.StrictMode></React.StrictMode>

所以更好的方法是使用 forwardRef 如果您可以访问子组件,另一种选择是使用包装子组件的包装器 div 并像这样使用 useRef

<div ref={editorRef} >
<ChildComp/>
</div> 

这将允许您访问 getBoundingClientRect() 可能会返回错误的大小(rect.top 0,rect.height 0 等),在这种情况下您需要延迟调用它

useEffect(() => {

setTimeout(() => {
   var rect = editorRef.current.getBoundingClientRect();
}, 300);

  }, [ ]);

推荐阅读