React报错之Object is possibly null的问题及解决方法

目录
  • 类型守卫
  • 非空断言
  • 总结

类型守卫

使用类型守卫来解决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中,感叹号标记被称为非空断言操作符。被用来从类型中移除nullundefined ,而不用进行任何显式的类型检查。

当我们使用非空断言时,基本上我们就是在告诉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元素,或在我们的代码中稍后设置其值。

到此这篇关于React报错之Object is possibly null的文章就介绍到这了,更多相关React  Object is possibly null报错内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • npx create-react-app xxx创建项目报错的解决办法

    手头有一台大学时代的Windows电脑,它此前没有装过create-react-app,只装了node环境.版本信息:node -> 10.16.3,npm -> 6.9.0.前几日闲的无事想给它装个React,结果失败了,报了错,所以有了下面这出. 安装过程 根据React官方文档(上图)可以发现,此时并不需要安装create-react-app工具,只要你的node >= 8.10 && npm >= 5.6,就可以直接使用npx create-react-ap

  • React报错之组件不能作为JSX组件使用的解决方法

    目录 总览 返回单个JSX元素 不要忘记返回值 更新React类型声明 总览 组件不能作为JSX组件使用,出现该错误有多个原因: 返回JSX元素数组,而不是单个元素. 从组件中返回JSX元素或者null以外的任何值. 使用过时的React类型声明. 返回单个JSX元素 下面是一个错误如何发生的示例. // App.tsx // ️ 'App' cannot be used as a JSX component. // Its return type 'Element[]' is not a va

  • 解决react中label标签for报错问题

    要求:点击账号或密码,自动将焦点转到相关的表单控件(input)上. 问题:功能可以使用,但是会有报错. 解决办法:react中label标签没有for属性,用htmlFor代替for属性 demo的代码: 报错 修改后的代码 到此这篇关于react中label标签for报错的文章就介绍到这了,更多相关react中label标签内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

  • React报错之Object is possibly null的问题及解决方法

    目录 类型守卫 非空断言 总结 类型守卫 使用类型守卫来解决React中useRef钩子“Object is possibly null”的错误.比如说,if (inputRef.current) {} .一旦null被排除在ref的类型之外,我们就能够访问ref上的属性. 下面是一个错误如何发生的示例. import {useEffect, useRef} from 'react'; export default function App() { const inputRef = useRef

  • React报错之Parameter event implicitly has an any type解决

    目录 引言 总览 设置类型 逃生舱any 确定类型 引言 原文链接:bobbyhadz.com/blog/react-… 作者:Borislav Hadzhiev 正文从这开始~ 总览 当我们不在事件处理函数中为事件声明类型时,会产生"Parameter 'event' implicitly has an 'any' type"错误.为了解决该错误,显示地为event参数声明类型. 比如说,在input元素上,将处理change事件声明类型为React.ChangeEvent<H

  • Python3安装模块报错Microsoft Visual C++ 14.0 is required的解决方法

    问题一:安装模块时出现报错 Microsoft Visual C++ 14.0 is required,也下载安装了运行库依然还是这个错误 解决: 1.打开Unofficial Windows Binaries for Python Extension Packages(http://www.lfd.uci.edu/~gohlke/pythonlibs/),这里面有很多封装好的Python模块的运行环境 2.找到所需要下载的模块文件对应版本进行下载. 如,需要下载Pymssql,本机安装是32位

  • Mysql报错Duplicate entry '值' for key '字段名'的解决方法

    遇到这种问题, 是你的数据库表那个字段设置了唯一索引.所以这个字段新增的数据不能重复.具体可以打开表,然后点击表设置,具体教程可以看下文章最后 Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '测试' for key 'teacher.uk_name'    at sun.reflect.NativeConstructorAccessorI

  • Android Studio 报错failed to create jvm error code -4的解决方法

    安装完 Android Studio 后启动,却报错如下: 复制代码 代码如下: failed to create jvm error code -4 这一般应是内存不够用所致,解决方法参考如下. 打开 Android Studio 安装目录下的bin目录,查找并打开文件 studio.exe.vmoptions,修改代码: 复制代码 代码如下: -Xmx512m 为 -Xmx256m 保存后应即可正常打开了.

  • MongoDB添加仲裁节点报错:replica set IDs do not match的解决方法

    背景: 由于历史原因,某个MongoDB副本集只有一主一从双节点,无法满足自动故障转移要求,需要配置一个仲裁节点. 原有节点192.168.10.20:27017,192.168.10.21:27017,现在准备在20上配置一个新节点27018当做仲裁 在当前主节点上执行 repset:PRIMARY> cfg={_id:"repset", members:[{_id:0, host:'192.168.10.20:27017', priority:1},{_id:2, host:

  • Vue 报错TypeError: this.$set is not a function 的解决方法

    报错场景:将APi中得到的response数据,用Vue$set()使数据动态响应 报错代码: methods: { textTranslate: function (text, to) { $.ajax({ url: 'http://openapi.youdao.com/api', type: 'post', dataType: 'jsonp', data: { q: text, appKey: this.appKey, salt: this.salt, from: this.from, to

  • git 报错:OpenSSL SSL_read: Connection was reset, errno 10054 解决方法

    git 报错信息:OpenSSL SSL_read: Connection was reset, errno 10054 Git 中 push 报错 OpenSSL SSL_read: Connection was reset, errno 10054 ... 异常信息 Git Bash 中,push 时,出现错误 git push -u origin main OpenSSL SSL_read: Connection was reset, errno 10054 ... 解决方案 1. 邮箱问

  • linux mount报错:you must specify the filesystem type的解决方法

    最近工作中遇到一个问题,在linux mount /dev/vdb 到 /home 分区时报错: # mount /dev/vdb /home mount: you must specify the filesystem type 先执行:mkfs.ext3 /dev/vdb # mkfs.ext3 /dev/vdb mke2fs 1.41.12 (17-May-2010) Filesystem label= OS type: Linux Block size=4096 (log=2) Frag

随机推荐