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中,感叹号标记被称为非空断言操作符。被用来从类型中移除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元素,或在我们的代码中稍后设置其值。
React报错之Object is possibly null的更多相关文章
- oracle创建包后执行报错:object omgmig.test_package is invalid.
		
今天学习了一下oracle的包的写法,然后碰到这么个问题.包声明和包主体都正确,但是就是执行报错:object omgmig.test_package is invalid. 这是会报错的sql,看起 ...
 - react 报错的堆栈处理
		
react报错 Warning: You cannot PUSH the same path using hash history 在Link上使用replace 原文地址https://reactt ...
 - python报错'str' object is not callable
		
>>> x=1.235 >>> int(x) 1 >>> str="fsgavfdbafdbntsbgbt" >> ...
 - Spring Boot整合Swagger报错:"this.condition" is null
		
前段时间看到群里有吐槽swagger整合问题,当时没仔细看,总以为是姿势不对. 这两天正好自己升级Spring Boot版本,然后突然出现了这样的一个错误: Caused by: java.lang. ...
 - React报错之Cannot find namespace context
		
正文从这开始~ 总览 在React中,为了解决"Cannot find namespace context"错误,在你使用JSX的文件中使用.tsx扩展名,在你的tsconfig. ...
 - tomcat启动时候报错Can't convert argument: null
		
一.启动报错: 为了避免导入的项目重名,我先修改了前一个项目的名称. 重新启动该项目至tomcat,报错:java.lang.IllegalArgumentException: Cant conver ...
 - 报错:org.hibernate.AssertionFailure: null id in com.tt.hibernate.entities.News entry (don't flush the Session after an exception occurs)
		
在使用hibernate创建数据库的表格时,出现了如下报错: 十二月 28, 2016 10:17:02 上午 org.hibernate.tool.hbm2ddl.SchemaExport perf ...
 - [terry笔记]IMPDP报错ORA-39083 Object type TYPE failed to create  ORA-02304
		
今天在使用impdp导入的时候(同一数据库中转换schema),遇到了 ORA-39083: Object type TYPE failed to create with error: ORA-023 ...
 - 【.NET调用Python脚本】C#调用python requests类库报错 'module' object has no attribute '_getframe' - IronPython 2.7
		
最近在开发微信公众号,有一个自定义消息回复的需求 比如用户:麻烦帮我查询一下北京的天气? 系统回复:北京天气,晴,-℃... 这时候需要根据关键字[北京][天气],分词匹配需要执行的操作,然后去调用天 ...
 
随机推荐
- .netcore6.0自己配置swagger
			
环境:.net core6.0 一.安装依赖包:Swashbuckle.AspNetCore 二.右击项目->属性->生成->输出,勾选文档文件,然后配置文件生成路径,注意是相对路径 ...
 - 深入解读SQL的聚集函数
			
摘要:本文从基本聚集操作入手,介绍常用的SQL语法,以及一些扩展的聚集功能,同时会讲到在GaussDB(DWS)里聚集相关的一些优化思路. 本文分享自华为云社区<GaussDB(DWS) SQL ...
 - jQuery基础入门+购物车案例详解
			
jQuery是一个快速.简洁的JavaScript代码库(或JavaScript框架).jQuery设计的宗旨是"write Less,Do More",即倡导写更少的代码,做更多 ...
 - dubbo是如何实现可扩展的?
			
dubbo如何实现可扩展的,援引官网描述: Dubbo 的扩展点加载从 JDK 标准的 SPI (Service Provider Interface) 扩展点发现机制加强而来. Dubbo 改进了 ...
 - Java ES 实现or查询
			
es mapping里有三个字段: A:Integer B:Integer C:TEXT 现在想实现一个查询,来检索 ( (A =1 and B=2) or (c like "test ...
 - [python][flask] Flask 图片上传与下载例子(支持漂亮的拖拽上传)
			
目录 1.效果预览 2.新增逻辑概览 3.tuchuang.py 逻辑介绍 3.1 图片上传 3.2 图片合法检查 3.3 图片下载 4.__init__.py 逻辑介绍 5.upload.html ...
 - Pycharm连接远程服务器并保持文件夹同步
			
pycharm版本2021 服务器版本 Ubuntu 18 1.连接远程服务器 xxx这部省略了,因为之前就已经连接上了hh,后面用到再补充. 2.保持文件夹同步 1.首先在本地(windows环境创 ...
 - 自动装箱与自动拆箱——JavaSE基础
			
自动装箱与自动拆箱 自动装箱与拆箱就是编译器蜜糖(Compiler Sugar) Integer a = 234; // 自动装箱,实际上是Integer a = Integer.valueOF(23 ...
 - XSS防跨站脚本攻击-AntiSamy的基本使用
			
XSS:跨站脚本攻击(Cross Site Scripting),为不和 CSS混淆,故将跨站脚本攻击缩写为XSS.XSS是指恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页时,嵌入其 ...
 - 一文搞懂Kafka的基本原理及使用
			
Kafka的基本原理及使用 一.基本概念及原理 1.Kafka特点 Kafka 是一个分布式的流式平台,流式平台包括以下三个特点: 发布和订阅消息(流),类似于一个消息队列或企业消息系统 持久化收到的 ...