React报错之无法在未挂载的组件上执行React状态更新
正文从这开始~
总览
为了解决"Warning: Can't perform a React state update on an unmounted component" ,可以在你的useEffect钩子中声明一个isMounted布尔值,用来跟踪组件是否被安装。一个组件的状态只有在该组件被挂载时才会被更新。
import {useState, useEffect} from 'react';
const App = () => {
const [state, setState] = useState('');
useEffect(() => {
// ️ set isMounted to true
let isMounted = true;
async function fetchData() {
const result = await Promise.resolve(['hello', 'world']);
// ️ only update state if component is mounted
if (isMounted) {
setState(result);
}
}
fetchData();
return () => {
// ️ when component unmounts, set isMounted to false
isMounted = false;
};
}, []);
return (
<div>
<h2>State: {JSON.stringify(state)}</h2>
</div>
);
};
export default App;
当我们试图更新一个未挂载的组件的状态时,会出现"无法在未挂载的组件上执行React状态更新"的警告。
isMounted
摆脱该警告的直截了当的方式是,在useEffect钩子中使用isMounted布尔值来跟踪组件是否被挂载。
在useEffect中,我们初始化isMounted布尔值为true。
我们的fetchData 函数执行一些异步的任务,最常见的是一个API请求,并根据响应来更新状态。
然而,需要注意的是,我们只有当isMounted变量被设置为true时,才会更新状态。
async function fetchData() {
const result = await Promise.resolve(['hello', 'world']);
// ️ only update state if component is mounted
if (isMounted) {
setState(result);
}
}
这可以帮助我们避免警告,因为如果组件没有挂载,我们就不会更新状态。
当组件卸载时,从useEffect钩子返回的函数会被调用。
return () => {
// ️ when component unmounts, set isMounted to false
isMounted = false;
};
我们设置isMounted变量为false,表示该组件不再挂载。如果fetchData函数在组件卸载时被调用,if代码块不会执行是因为isMounted设置为false。
async function fetchData() {
const result = await Promise.resolve(['hello', 'world']);
// ️ only update state if component is mounted
if (isMounted) {
setState(result);
}
}
提取
如果经常这样做,可以将逻辑提取到可重用的钩子中。
import {useState, useEffect, useRef} from 'react';
// ️ extract logic into reusable hook
function useIsMounted() {
const isMounted = useRef(false);
useEffect(() => {
isMounted.current = true;
return () => {
isMounted.current = false;
};
});
return isMounted;
}
const App = () => {
const [state, setState] = useState('');
// ️ use hook
const isMountedRef = useIsMounted();
useEffect(() => {
async function fetchData() {
const result = await Promise.resolve(['hello', 'world']);
// ️ only update state if component is mounted
if (isMountedRef.current) {
setState(result);
}
}
fetchData();
}, [isMountedRef]);
return (
<div>
<h2>State: {JSON.stringify(state)}</h2>
</div>
);
};
export default App;
useRef()钩子可以传递一个初始值作为参数。该钩子返回一个可变的ref对象,其.current属性被初始化为传递的参数。
我们在useIsMounted钩子中跟踪组件是否被挂载,就像我们直接在组件的useEffect钩子中做的那样。
需要注意的是,在fetchData函数中,我们必须检查isMountedRef.current 的值,因为ref上的current属性是ref的实际值。
React报错之无法在未挂载的组件上执行React状态更新的更多相关文章
- VM中装Linux换ISO文件报错"该光盘无法被挂载"
一.发现问题 利用VM安装Red Hat Linux的时候,第一个iso安装完毕,准备换第二个iso,报错“该光盘无法被挂载”. 二.解决办法 上面的菜单栏中“虚拟机”—>“设置”—>“硬 ...
- Oracle添加记录的时候报错:违反完整性约束,未找到父项关键字
今天需要向一个没有接触过的一个Oracle数据库中添加一条记录,执行报错: 分析: 报错的根本原因:未找到父项关键字的原因是因为你在保存对象的时候缺失关联对象. 问题的解决思路:先保存关联对象后再保存 ...
- react 报错的堆栈处理
react报错 Warning: You cannot PUSH the same path using hash history 在Link上使用replace 原文地址https://reactt ...
- [转]ORACLE 11G 导出报错(EXP-00003)未找到段 (0,0) 的存储定义
http://blog.csdn.net/qq_19524879/article/details/51313205 ORACLE 11G 导出报错(EXP-00003)未找到段 (0,0) 的存储定义 ...
- 解决Oracle+Mybatis批量插入报错:SQL 命令未正确结束
Mybatis批量插入需要foreach元素.foreach元素有以下主要属性: (1)item:集合中每一个元素进行迭代时的别名. (2)index:指定一个名字,用于表示在迭代过程中,每次迭代到的 ...
- 报错:该字符串未被识别为有效的DateTime
报错:该字符串未被识别为有效的DateTime □ 背景 前端的搜索条件中包含关于时间的字符串,由jquery ui的datepicker产生时间字符串. 服务端对时间做了一次转换:DateTime. ...
- 小程序报错:出现脚本错误或者未正确调用 Page()的解决办法
场景是两个人共同开发小程序,我使用的是pc端,另一个同事是用的mac端,我这边能够正常运行项目,代码提交到git,同事check下来发现运行报错: 出现脚本错误或者未正确调用 Page(); 如图 一 ...
- React报错之Cannot find namespace context
正文从这开始~ 总览 在React中,为了解决"Cannot find namespace context"错误,在你使用JSX的文件中使用.tsx扩展名,在你的tsconfig. ...
- angularjs 遇见$scope,xxx=function()报错为该函数未定义
本包子今天遇见一个问题,就是明明写了$scope,xx=function()但是报错了,报错显示是该函数未定义,我就很着急的先将函数写成一个全局函数,就没问题,等下午有空的时候寻思了一下,为什么全局就 ...
随机推荐
- CentOS6安装PLEX
CentOS6安装PLEX 一.安装使用PLEX 1.1 安装 1)下载 https://www.plex.tv/downloads/ plexmediaserver-1.11.3.4803-c40b ...
- 【JNPF修改通告】fastjson≤1.2.80反序列化漏洞
近日Fastjson Develop Team 发现 fastjson 1.2.80及以下存在新的风险,存在反序列化漏洞.攻击者可绕过默认autoType关闭限制,攻击远程服务器,风险影响较大,请大家 ...
- Typecho博客转移服务器,数据备份.
目录 Typecho博客转移服务器,数据备份. 简述操作(有基础的mjj看这个简述就可以了.) 详细步骤(建议小白来看, 已经在很多详细方面进行说明了.) 备份篇 备份导入与数据库转移篇 重新部署ty ...
- SQL Server之自动创建视图
本方法只适合特定模式的视图创建. 比如,创建需要整张表列名的视图,或者当表和需要的列名统计在一张数据表当中,如图所示: 首先要先获取要创建视图所需要的表,这里我获取的是整个数据库中的表, IF OBJ ...
- GDKOI 2021 Day1 PJ 爆炸记
早上睡到 7:10 分才想起今天有 GDKOI ,赶紧去买了一个面包赶去机房 发现隔壁的大奆都过来了.比赛时由于昨晚一直没睡好,打了两个小时的哈欠 T1 :暴力模拟 根据 \(r\) 和 \(c\) ...
- Spring框架系列(4) - 深入浅出Spring核心之面向切面编程(AOP)
在Spring基础 - Spring简单例子引入Spring的核心中向你展示了AOP的基础含义,同时以此发散了一些AOP相关知识点; 本节将在此基础上进一步解读AOP的含义以及AOP的使用方式.@pd ...
- 关于swiper插件在vue2的使用
最近做项目用到了vue-awesome-swiper,总结一下使用方法 第一步:安装依赖 npm install swiper vue-awesome-swiper --save or npm ins ...
- idea 查看 类所有方法的快捷键
idea 查看 类 所有方法的快捷键 Idea:ctrl+F12 Eclipse:Ctrl+O
- 一文详解|Go 分布式链路追踪实现原理
在分布式.微服务架构下,应用一个请求往往贯穿多个分布式服务,这给应用的故障排查.性能优化带来新的挑战.分布式链路追踪作为解决分布式应用可观测问题的重要技术,愈发成为分布式应用不可缺少的基础设施.本文将 ...
- Linux YUM制作自己的yum repository
Linux YUM制作自己的yum repository 配置步骤: 1.通过网络发布自己的package目录 2.创建本地repository 3.配置自己的yum源 操作实现: 1 安装creat ...