开发者问题收集

React,useRef 不允许访问当前属性,获取未捕获的 TypeError:无法读取未定义的属性(读取“clientHeight”)

2022-03-12
2910

我使用以下方法存储对图像项的引用: const renderImageRef = useRef() 。然后使用以下方法在 render() 函数中分配引用:

<img ref={renderedImageRef} src=... />

在下面的另一个 JSX 项中,我尝试使用以下方法访问 renderedImageRef.current.clientHeight

<div style={{top:`${renderedImageRef.current.clientHeight}px`}}>
   Hello world
</div>

但这会在控制台中产生错误:

Uncaught TypeError: Cannot read properties of undefined (reading 'clientHeight')

奇怪的是,如果我尝试从 useEffect 钩子内部访问 renderedImageRef.current.clientHeight ,它会正确显示高度:

useEffect(() => {
    if(renderedImageRef !== null) {
        console.log(renderedImageRef)
    }
}, [renderedImageRef])

为什么我会收到控制台错误?

2个回答

可能的答案是,此行:

<div style={{top:`${renderedImageRef.current.clientHeight}px`}}>Hello world</div>

出现在您的代码中,早于此行:

<img ref={renderedImageRef} src=... />

在这种情况下,出现错误是正常的。需要知道的是,当您调用 const renderedImageRef = useRef() 时, renderedImageRef 的值为 {current:undefined 。必须在 refcurrent 字段中获取其值之前呈现 JSX。

解决方案是使用 top 的状态:

const [top, setTop] = useState(0);
useEffect(() => {
  // At this point, the current is defined. This if is useful in case you use TypeScript
  if (renderedImageRef.current) {
    setTop(renderedImageRef.current.clientHeight);
  }
}, []);
<div style={{top:`${top}px`}}>Hello world</div>
Youssouf Oumar
2022-03-12

如果您使用的是 Next.JS,我认为您必须将依赖项更改为 renderImageRef.current。因此如下所示:

const [top, setTop]=useState(0)
useEffect(() => {
    if(renderedImageRef.current) {
        setTop(renderedImageRef.current.clientHeight);
    }
}, [renderedImageRef.current])
howard
2022-04-28