reactjs - 為什麼 `ref.current.clientHeight` 總是可能為 null?
我正在嘗試找出該元件的高度(以像素為單位),因為它的高度將在 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 };
答案#1
ref 永遠不會是 null,因為它是 const,一開始就不是 null,所以 if (ref) 是沒用的。
useRef<T>(x: T | null) 的類型是 MutableRefObject<T>。在這裡,T 是 null,所以 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);
}
});
答案#2
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 原生的功能,所以它運作得非常順利。
