React報(bào)錯(cuò)之Object?is?possibly?null的問(wèn)題及解決方法
類型守衛(wèi)
使用類型守衛(wèi)來(lái)解決React中useRef鉤子“Object is possibly null”的錯(cuò)誤。比如說(shuō),if (inputRef.current) {} 。一旦null被排除在ref的類型之外,我們就能夠訪問(wèn)ref上的屬性。

下面是一個(gè)錯(cuò)誤如何發(fā)生的示例。
import {useEffect, useRef} from 'react';
export default function App() {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
// ?? Object is possibly 'null'.ts(2531)
inputRef.current.focus();
}, []);
return (
<div>
<input ref={inputRef} type="text" id="message" />
<button>Click</button>
</div>
);
}
代碼片段中的問(wèn)題是,TypeScript不能確保我們將一個(gè)元素或者一個(gè)值賦值給ref,所以它的current屬性可能為null。
為了解決這個(gè)錯(cuò)誤,在訪問(wèn)ref類型上的屬性之前,我們必須使用類型守衛(wèi)來(lái)從其類型中排除null。
import {useEffect, useRef} from 'react';
export default function App() {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
// ??? ref could be null here
if (inputRef.current != null) {
// ??? TypeScript knows that ref is not null here
inputRef.current.focus();
}
}, []);
return (
<div>
<input ref={inputRef} type="text" id="message" />
<button>Click</button>
</div>
);
}
我們使用簡(jiǎn)單的if語(yǔ)句作為類型守衛(wèi),來(lái)確保ref上的current屬性不存儲(chǔ)null。當(dāng)程序進(jìn)入到if代碼塊中,TypeScript就會(huì)知道ref對(duì)象上的current屬性就不會(huì)存儲(chǔ)null。
確保在useRef鉤子上使用泛型,正確的類型聲明ref上的current屬性。
注意,我們傳遞了一個(gè)泛型來(lái)將ref的值類型聲明為HTMLInputElement。
一些常用的類型有:HTMLInputElement,HTMLButtonElement,HTMLAnchorElement,HTMLImageElement,HTMLTextAreaElement,HTMLSelectElement 等等。
如果你在ref中存儲(chǔ)了不同的值,請(qǐng)確保將特定類型傳遞給useRef鉤子的泛型,例如const ref = useRef<{name: string}>(null); 。
如果ref上的current屬性存儲(chǔ)了null,我們也可以使用可選鏈?. 操作符進(jìn)行短路運(yùn)算。
import {useEffect, useRef} from 'react';
export default function App() {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
// ??? optional chaining (?.)
inputRef.current?.focus();
}, []);
return (
<div>
<input ref={inputRef} type="text" id="message" />
{/* Cannot find name 'button'.ts(2304) */}
<button>Click</button>
</div>
);
}
如果引用是空值(null或者undefined),可選鏈?.操作符會(huì)進(jìn)行短路運(yùn)算,而不會(huì)拋出錯(cuò)誤。換句話說(shuō),如果ref上的current屬性存儲(chǔ)了null,操作符會(huì)短路運(yùn)算從而返回undefined。而不會(huì)在undefined上嘗試調(diào)用focus方法,導(dǎo)致一個(gè)運(yùn)行時(shí)錯(cuò)誤。
非空斷言
另一種解決方案是使用非空斷言!操作符。
import {useEffect, useRef} from 'react';
export default function App() {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
// ??? using non-null (!) assertion
inputRef.current!.focus();
}, []);
return (
<div>
<input ref={inputRef} type="text" id="message" />
{/* Cannot find name 'button'.ts(2304) */}
<button>Click</button>
</div>
);
}
在TypeScript中,感嘆號(hào)標(biāo)記被稱為非空斷言操作符。被用來(lái)從類型中移除null和undefined ,而不用進(jìn)行任何顯式的類型檢查。
當(dāng)我們使用非空斷言時(shí),基本上我們就是在告訴TS,ref對(duì)象上的current屬性不會(huì)存儲(chǔ)null或者undefined。
請(qǐng)注意,這種方法不是類型安全的,因?yàn)門ypeScript不執(zhí)行任何檢查以確保屬性不是空的。
總結(jié)
造成 "Object is possibly null"的錯(cuò)誤是因?yàn)?code>useRef()鉤子可以傳遞一個(gè)初始值作為參數(shù),而我們傳遞null作為初始值。該鉤子返回一個(gè)可變的ref對(duì)象,其.current屬性被初始化為所傳遞的參數(shù)。
當(dāng)傳遞ref prop給一個(gè)元素時(shí),比如<input ref={myRef} /> ,React將ref對(duì)象的.current屬性設(shè)置為相應(yīng)的DOM節(jié)點(diǎn),但TypeScript無(wú)法確定我們是否會(huì)將ref設(shè)置為DOM元素,或在我們的代碼中稍后設(shè)置其值。
到此這篇關(guān)于React報(bào)錯(cuò)之Object is possibly null的文章就介紹到這了,更多相關(guān)React Object is possibly null報(bào)錯(cuò)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- React Native:react-native-code-push報(bào)錯(cuò)的解決
- React報(bào)錯(cuò)之Parameter event implicitly has an any type解決
- react創(chuàng)建項(xiàng)目啟動(dòng)報(bào)錯(cuò)的完美解決方法
- react項(xiàng)目升級(jí)報(bào)錯(cuò),babel報(bào)錯(cuò),.babelrc配置兼容等問(wèn)題及解決
- React報(bào)錯(cuò)解決之ref返回undefined或null
- 解決React報(bào)錯(cuò)Property?'value'?does?not?exist?on?type?EventTarget
相關(guān)文章
React通過(guò)ref獲取子組件的數(shù)據(jù)和方法
這篇文章主要介紹了React如何通過(guò)ref獲取子組件的數(shù)據(jù)和方法,文中有詳細(xì)的總結(jié)內(nèi)容和代碼示例,具有一定的參考價(jià)值,需要的朋友可以參考下2023-10-10
React-Native做一個(gè)文本輸入框組件的實(shí)現(xiàn)代碼
這篇文章主要介紹了React-Native做一個(gè)文本輸入框組件的實(shí)現(xiàn)代碼,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-08-08
React Native之prop-types進(jìn)行屬性確認(rèn)詳解
本篇文章主要介紹了React Native之prop-types進(jìn)行屬性確認(rèn)詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
React如何通過(guò)@craco/craco代理接口
這篇文章主要介紹了React如何通過(guò)@craco/craco代理接口問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
react+antd.3x實(shí)現(xiàn)ip輸入框
這篇文章主要為大家詳細(xì)介紹了react+antd.3x實(shí)現(xiàn)ip輸入框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
React組件對(duì)子組件children進(jìn)行加強(qiáng)的方法
這篇文章主要給大家介紹了關(guān)于React組件中對(duì)子組件children進(jìn)行加強(qiáng)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用React具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
React函數(shù)組件傳參的實(shí)現(xiàn)
React函數(shù)組件通過(guò)接受props實(shí)現(xiàn)組件間的數(shù)據(jù)傳遞,通過(guò)組件標(biāo)簽的屬性向子組件傳遞數(shù)據(jù),并在子組件中通過(guò)參數(shù)接收,還可以使用ES6的解構(gòu)賦值,函數(shù)也能作為props傳遞,以實(shí)現(xiàn)父子組件間的交互和通信,下面就來(lái)具體了解一下2024-09-09
react router 4.0以上的路由應(yīng)用詳解
本篇文章主要介紹了react router 4.0以上的路由應(yīng)用詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09

