網站首頁 編程語言 正文
解決React報錯Property?'X'?does?not?exist?on?type?'HTMLElement'_React
作者:Borislav?Hadzhiev ? 更新時間: 2023-01-01 編程語言總覽
在React中,當我們試圖訪問類型為HTMLElement
的元素上不存在的屬性時,就會發生Property 'X' does not exist on type 'HTMLElement'錯誤。為了解決該錯誤,在訪問屬性之前,使用類型斷言來正確地類型聲明元素。
這里有三個例子來展示錯誤是如何發生的。
// App.tsx import {useEffect} from 'react'; export default function App() { useEffect(() => { const input = document.getElementById('first_name'); // ?? Property 'value' does not exist on type 'HTMLElement'.ts(2339) console.log(input?.value); // ----------------------------------------------------------------- const link = document.getElementById('link'); // ?? Property 'href' does not exist on type 'HTMLElement'.ts(2339) console.log(link?.href); // ----------------------------------------------------------------- const button = document.getElementById('btn'); if (button != null) { // ?? Property 'disabled' does not exist on type 'HTMLElement'.ts(2339) button.disabled = true; } }, []); return ( <div> <input id="first_name" type="text" name="first_name" defaultValue="Initial Value" /> <a id="link" href="<https://google.com>" target="_blank" > Open Google </a> <button id="btn">Submit</button> </div> ); }
產生錯誤的原因是,document.getElementById
方法的返回類型是HTMLElement | null
,但是我們試圖訪問的屬性不存在于HTMLElement
類型。
類型斷言
為了解決這個錯誤,使用類型斷言來為元素正確地進行類型聲明。比如說,類型斷言為HTMLInputElement
,?HTMLButtonElement
,?HTMLAnchorElement
,?HTMLImageElement
,?HTMLDivElement
,?HTMLTextAreaElement
等等。這取決于你所處理的元素。
這些類型始終命名為HTML***Element
。一旦你開始輸入HTML…
,你的IDE將會幫你自動補全。
import {useEffect} from 'react'; export default function App() { useEffect(() => { // ? type elements correctly via type assertions const input = document.getElementById('first_name') as HTMLInputElement; console.log(input?.value); const link = document.getElementById('link') as HTMLAnchorElement; console.log(link?.href); const button = document.getElementById('btn') as HTMLButtonElement; if (button != null) { button.disabled = true; } }, []); return ( <div> <input id="first_name" type="text" name="first_name" defaultValue="Initial Value" /> <a id="link" href="<https://google.com>" target="_blank" > Open Google </a> <button id="btn">Submit</button> </div> ); }
類型斷言被用于我們知道值的類型信息,但是TypeScript卻不知道的時候。
我們明確的告訴TypeScript,input
變量上存儲了HTMLInputElement
,并讓TS不要擔心。
同樣的,我們將link
變量類型聲明為HTMLAnchorElement
,將btn
變量類型聲明為HTMLButtonElement
。
你可以在訪問一個屬性之前,內聯使用類型斷言。
import {useEffect} from 'react'; export default function App() { useEffect(() => { const value = (document.getElementById('first_name') as HTMLInputElement).value; console.log(value); }, []); return ( <div> <input id="first_name" type="text" name="first_name" defaultValue="Initial Value" /> <a id="link" href="<https://google.com>" target="_blank" > Open Google </a> <button id="btn">Submit</button> </div> ); }
如果你只需要訪問屬性一次,并且不希望將元素分配給變量,那么內聯類型聲明可以完成這項工作。
如果你想更精確地處理元素的類型,可以使用聯合類型將類型聲明為HTML***Element | null
。
import {useEffect} from 'react'; export default function App() { useEffect(() => { const input = document.getElementById( 'first_name', ) as HTMLInputElement | null; console.log(input?.value); const link = document.getElementById('link') as HTMLAnchorElement | null; console.log(link?.href); const button = document.getElementById('btn') as HTMLButtonElement | null; if (button != null) { button.disabled = true; } }, []); return ( <div> <input id="first_name" type="text" name="first_name" defaultValue="Initial Value" /> <a id="link" href="<https://google.com>" target="_blank" > Open Google </a> <button id="btn">Submit</button> </div> ); }
HTML***Element
或者null
類型是最準確的類型,因為如果DOM元素上不存在id
屬性,那么document.getElementById()
將會返回null
。
你可以使用可選鏈操作符(?.
)在訪問屬性之前來進行短路運算,如果引用是空值(null
或者undefined
)的話。
或者,你可以使用簡單的if
語句作為類型守衛,就像我們對button
處理的那樣。
總結
最佳實踐是在類型斷言中包含null
。因為如果元素上面不提供id
屬性,那么getElementById
方法將會返回null
。
原文鏈接:https://juejin.cn/post/7126539996076441613
相關推薦
- 2022-08-19 一篇文章讓你看懂用git上傳文件至gitee,結尾有.gitignore配置
- 2023-04-19 Git 推送報錯:error: GH007: Your push would publish a p
- 2022-04-12 React工作流程及Error?Boundaries實現過程講解_React
- 2022-09-18 iOS?xcconfig編寫示例教程_IOS
- 2022-06-09 忘記Grafana不要緊2種Grafana重置admin密碼方法詳細步驟_服務器其它
- 2022-07-01 react-router-dom?V6的配置使用實踐_React
- 2023-03-20 Redis腦裂導致數據丟失的解決_Redis
- 2022-07-01 Oracle的約束介紹與約束維護_oracle
- 最近更新
-
- 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同步修改后的遠程分支