解决React报错Property 'X' does not exist on type 'HTMLElement'

目录
  • 总览
  • 类型断言
  • 总结

总览

在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>" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  target="_blank" rel="noreferrer">
        Open Google
      </a>
      <button id="btn">Submit</button>
    </div>
  );
}

产生错误的原因是,document.getElementById方法的返回类型是HTMLElement | null,但是我们试图访问的属性不存在于HTMLElement 类型。

类型断言

为了解决这个错误,使用类型断言来为元素正确地进行类型声明。比如说,类型断言为HTMLInputElementHTMLButtonElementHTMLAnchorElementHTMLImageElementHTMLDivElementHTMLTextAreaElement等等。这取决于你所处理的元素。

这些类型始终命名为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>" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  target="_blank" rel="noreferrer">
        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>" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  target="_blank" rel="noreferrer">
        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>" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  target="_blank" rel="noreferrer">
        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

以上就是解决React报错Property 'X' does not exist on type 'HTMLElement'的详细内容,更多关于React报错解决Property X的资料请关注我们其它相关文章!

(0)

相关推荐

  • React报错Type '() => JSX.Element[]' is not assignable to type FunctionComponent

    目录 总览 React片段 React.Fragment div 总结 总览 当我们尝试从函数组件中返回元素组成的数组时,会产生"Type '() => JSX.Element[]' is not assignable to type FunctionComponent"错误.为了解决该错误,可以将元素数组包裹在React片段中. 这里有个示例用来展示错误是如何发生的. // App.tsx import React from 'react'; // ️ Type '() =&g

  • Objects are not valid as a React child报错解决

    目录 总览 map JSON.stringify Date 花括号 async 总结 总览 当我们尝试在JSX代码中,直接渲染对象或者数组时,会产生"Objects are not valid as a React child"错误.为了解决该错误,在JSX代码中,使用map()方法来渲染数组或者访问对象的属性. 下面是错误如何发生的示例. export default function App() { const employees = [ {id: 1, name: 'Alice'

  • Can't perform a React state update on an unmounted component报错解决

    目录 总览 isMounted 提取 总览 为了解决"Warning: Can't perform a React state update on an unmounted component" ,可以在你的useEffect钩子中声明一个isMounted布尔值,用来跟踪组件是否被安装.一个组件的状态只有在该组件被挂载时才会被更新. import {useState, useEffect} from 'react'; const App = () => { const [sta

  • 解决React报错React.Children.only expected to receive single React element child

    目录 总览 React片段 DOM元素 总览 当我们把多个子元素传递给一个只期望有一个React子元素的组件时,会产生"React.Children.only expected to receive single React element child"错误.为了解决该错误,将所有元素包装在一个React片段或一个封闭div中. 这里有个示例来展示错误是如何发生的. // App.js import React from 'react'; function Button(props)

  • 解决React报错No duplicate props allowed

    目录 总览 className 总结 总览 当我们为相同的组件传递相同的属性多次时,就会导致"No duplicate props allowed"警告.为了解决该警告,请确保只传递一次该属性.比如说,如果传递多次className属性,将它们连接成一个空格分隔的字符串. 下面的示例用来展示如何导致警告的. const App = () => { // ️ JSX elements cannot have multiple attributes with the same nam

  • React报错Function components cannot have string refs

    目录 总览 useRef 不会重新渲染 总览 当我们在一个函数组件中使用一个字符串作为ref时,会产生"Function components cannot have string refs"错误.为了解决该错误,使用useRef()钩子来得到一个可变的ref对象,这样你就可以在组件中作为ref使用. 这里有个示例用来展示错误是如何发生的. // App.js export default function App() { // A string ref has been found

  • React报错Too many re-renders解决

    目录 总览 传递函数 传递依赖 移入依赖 传递对象属性 记忆值 总览 产生"Too many re-renders. React limits the number of renders to prevent an infinite loop"错误有多方面的原因: 在一个组件的渲染方法中调用一个设置状态的函数. 立即调用一个事件处理器,而不是传递一个函数. 有一个无限设置与重渲染的useEffect钩子. 这里有个示例来展示错误是如何发生的: import {useState} fro

  • 解决React报错Property 'X' does not exist on type 'HTMLElement'

    目录 总览 类型断言 总结 总览 在React中,当我们试图访问类型为HTMLElement 的元素上不存在的属性时,就会发生Property 'X' does not exist on type 'HTMLElement'错误.为了解决该错误,在访问属性之前,使用类型断言来正确地类型声明元素. 这里有三个例子来展示错误是如何发生的. // App.tsx import {useEffect} from 'react'; export default function App() { useEf

  • 解决React报错Property 'value' does not exist on type EventTarget

    目录 总览 正确声明类型 找出类型 总结 总览 当event参数的类型不正确时,会产生"Property 'value' does not exist on type EventTarget"错误.为了解决该错误,将event的类型声明为React.ChangeEvent<HTMLInputElement> .然后就可以通过event.target.value 来访问其值. 这里有个示例用来展示错误是如何发生的. // App.tsx function App() { //

  • 解决React报错Property does not exist on type 'JSX.IntrinsicElements'

    目录 总览 组件大写 类型声明 总结 总览 当组件名称以小写字母开头时,会导致"Property does not exist on type 'JSX.IntrinsicElements'"错误.为了解决该错误,确保组件名称总是以大写字母开头,安装React声明文件并重启你的开发服务器. 这里有个示例用来展示错误是如何发生的. // App.tsx // ️ name starts with lowercase letter function myComponent() { retu

  • 解决React报错Parameter 'props' implicitly has an 'any' type

    目录 总览 安装类型文件 声明类型 泛型 重新安装 总览 当我们没有为函数组件或者类组件的props声明类型,或忘记为React安装类型声明文件时,会产生"Parameter 'props' implicitly has an 'any' type"错误.为了解决这个错误,在你的组件中明确地为props对象设置一个类型. 安装类型文件 你首先要确定的是你已经安装了React类型声明文件.在项目的根目录下打开终端,并运行以下命令. # ️ with NPM npm install --s

  • vscode中的vue项目报错Property ‘xxx‘ does not exist on type ‘CombinedVueInstance<{ readyOnly...Vetur(2339)

    问题描述: 今天早上一开机,打开项目,发现项目一片醒目的红色,查看报错原因提示: Property 'xxxx' does not exist on type 'CombinedVueInstance<{ readyOnly: unknown; businessPrice: unknown; travelStaffInfo: any; } & Record<never, any> & Vue, object, object, object, Record<never

  • 解决React报错Cannot assign to 'current' because it is a read-only property

    目录 总览 正确的泛型 DOM元素 总览 当我们用一个null值初始化一个ref,但在其类型中不包括null时,就会发生"Cannot assign to 'current' because it is a read-only property"错误.为了解决该错误,请在ref的类型中包含null.比如说,const ref = useRef<string | null>(null) . 这里有个例子来展示错误是如何发生的. // App.tsx import {useEf

  • 解决React报错useNavigate() may be used only in context of Router

    目录 总览 useNavigate Jest replace 总览 当我们尝试在react router的Router上下文外部使用useNavigate 钩子时,会产生"useNavigate() may be used only in the context of a Router component"警告.为了解决该问题,只在Router上下文中使用useNavigate 钩子. 下面是一个在index.js文件中将React应用包裹到Router中的例子. // index.j

  • 解决React报错Style prop value must be an object

    目录 总览 映射 提取 总览 在React中,当我们为元素的style 属性传递字符串时,会产生"Style prop value must be an object"警告.为了解决该警告,使用从属性到值的映射.比如说,style={{paddingLeft: '15px'}} . 这里有个例子来展示错误是如何发生的. // App.js const App = () => { // ️ Style prop value must be an object eslint(reac

  • 解决React报错The tag is unrecognized in this browser

    目录 总览 确保标签存在 小写字母开头 总览 当我们使用一个在浏览器中不存在的标签或以小写字母开头的组件名称时,会产生"The tag is unrecognized in this browser"React警告.为了解决该问题,只使用有效的标签名称,并将你的组件的第一个字母大写. 这里有个例子来展示错误是如何发生的. // App.js const App = () => { // ️ Warning: The tag <p1> is unrecognized i

  • 解决React报错Functions are not valid as a React child

    目录 总览 调用函数 总结 总览 产生"Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render."错误 通常是因为以下两个原因: 从render中返回一个函数引用而不是一个组件. 使用 react router 路由作为<Route path="/about" el

随机推荐