开发者问题收集

为什么“ref.current.clientHeight”总是可能为空?

2020-04-14
11552

我正在尝试找到组件的高度(以像素为单位),因为它的高度将在 CSS 中设置为 100%

import React, { useState, useLayoutEffect, useRef } from "react";

function Scale() {
  const [height, setHeight] = useState(0);
  const ref = useRef(null);
  useLayoutEffect(() => {
    if (ref && ref.current && ref.current.clientHeight) {
//                              ^ error: Object is possibly 'null'
      const height = ref.current.clientHeight;
      setHeight(height);
    }
  });
  return (
    <div className="scale" ref={ref}>
      {height}
    </div>
  );
}

export { Scale };
2个回答

ref 永远不会为 null ,因为它是 const ,并且一开始就不为 null,因此 if (ref) 毫无用处。

useRef<T>(x: T | null) 的类型是 MutableRefObject<T> 。此处, Tnull ,因此 ref.current 的类型为 null

要解决此问题,请指定设置后的类型:

  const ref = useRef(null as null | HTMLDivElement);
  // Or manually specify the type parameter
  const ref = useRef<HTMLDivElement>(null)
  useLayoutEffect(() => {
    if (ref.current && ref.current.clientHeight) {
      const height = ref.current.clientHeight;
      setHeight(height);
    }
  });
Artyer
2020-04-14
if (ref && ref.current && ref.current.clientHeight) {
   //                        ^ error: Object is possibly 'null'
   const height = ref.current.clientHeight;
   setHeight(height);
}

此语句应该可以工作,但是 TypeScript 通常不会像我们期望的那样进行推断。

因此,最好的解决方案(而不仅仅是一些黑客解决方法)是使用 Babel Optional Chaining 插件。

将其添加到您的 .babelrc.js ,然后您可以用

if (ref?.current?.clientHeight) {
   const height = ref.current.clientHeight;
   setHeight(height);
}
替换该语句>

它实际上是 TypeScript 3.7 的原生功能,因此效果非常好。

Pushkin
2020-04-14