網站首頁 編程語言 正文
類型守衛
使用類型守衛來解決React中useRef
鉤子“Object is possibly null”的錯誤。比如說,if (inputRef.current) {}
。一旦null
被排除在ref
的類型之外,我們就能夠訪問ref
上的屬性。
下面是一個錯誤如何發生的示例。
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> ); }
代碼片段中的問題是,TypeScript不能確保我們將一個元素或者一個值賦值給ref,所以它的current
屬性可能為null
。
為了解決這個錯誤,在訪問ref類型上的屬性之前,我們必須使用類型守衛來從其類型中排除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> ); }
我們使用簡單的if
語句作為類型守衛,來確保ref
上的current
屬性不存儲null
。當程序進入到if
代碼塊中,TypeScript就會知道ref
對象上的current
屬性就不會存儲null
。
確保在useRef鉤子上使用泛型,正確的類型聲明ref
上的current
屬性。
注意,我們傳遞了一個泛型來將ref
的值類型聲明為HTMLInputElement
。
一些常用的類型有:HTMLInputElement
,HTMLButtonElement
,HTMLAnchorElement
,HTMLImageElement
,HTMLTextAreaElement
,HTMLSelectElement
等等。
如果你在ref
中存儲了不同的值,請確保將特定類型傳遞給useRef
鉤子的泛型,例如const ref = useRef<{name: string}>(null);
。
如果ref
上的current
屬性存儲了null
,我們也可以使用可選鏈?.
操作符進行短路運算。
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
),可選鏈?.操作符會進行短路運算,而不會拋出錯誤。換句話說,如果ref
上的current
屬性存儲了null
,操作符會短路運算從而返回undefined
。而不會在undefined
上嘗試調用focus
方法,導致一個運行時錯誤。
非空斷言
另一種解決方案是使用非空斷言!
操作符。
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中,感嘆號標記被稱為非空斷言操作符。被用來從類型中移除null
和undefined
,而不用進行任何顯式的類型檢查。
當我們使用非空斷言時,基本上我們就是在告訴TS,ref
對象上的current
屬性不會存儲null
或者undefined
。
請注意,這種方法不是類型安全的,因為TypeScript不執行任何檢查以確保屬性不是空的。
總結
造成 "Object is possibly null"的錯誤是因為useRef()
鉤子可以傳遞一個初始值作為參數,而我們傳遞null
作為初始值。該鉤子返回一個可變的ref
對象,其.current
屬性被初始化為所傳遞的參數。
當傳遞ref prop給一個元素時,比如<input ref={myRef} />
,React將ref
對象的.current
屬性設置為相應的DOM節點,但TypeScript無法確定我們是否會將ref
設置為DOM元素,或在我們的代碼中稍后設置其值。
原文鏈接:https://www.cnblogs.com/chuckQu/p/16533611.html
相關推薦
- 2022-09-21 android實現簡單底部導航欄_Android
- 2022-12-22 關于Python?ImportError:?No?module?named?通用解決方法_pytho
- 2023-04-14 React超詳細講述Fiber的使用_React
- 2022-05-05 sqlserver數據庫加密后無法使用MDF,LDF,log文件名稱被修改的數據恢復_MsSql
- 2023-11-23 python的相對路徑表示方式
- 2023-01-10 Vmware虛擬機設置主機端口映射方式_VMware
- 2023-07-14 react 中redux的使用步驟
- 2022-02-21 React事件綁定詳解_React
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支