Can't perform a React state update on an unmounted component. This is a no-op......
- 本篇文章首先回顾一下什么是内存泄露,然后看两个 demo 观察 react 出现内存泄露的具体情况。
什么是内存泄露
-
程序的运行需要内存。只要程序提出要求,操作系统或者运行时(runtime)就必须供给内存。
-
对于持续运行的服务进程(daemon),必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。
-
不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)。
JavaScript 中常见的几种内存泄露
function leaks(){
leak = '***'; //leak 成为一个全局变量,不会被回收
var leaks = (function(){
var leak = '***';// 被闭包所引用,不会被回收
return function(){
console.log(leak);
document.querySelector("#demo").addEventListener('click', myFunction);
var para1=document.querySelector("#demo");
para1.parentNode.removeChild(para1);
如果我们在没有取消 click 方法前去销毁了 para1 节点,就会造成内存泄露。
正确的做法:
document.querySelector("#demo").addEventListener('click', myFunction);
// 我们需要在删除节点前清除挂载的 click 方法
document.querySelector("#demo").removeEventListener("click", myFunction);
var para1=document.querySelector("p1");
para1.parentNode.removeChild(para1);
为了更加了解 react 的内存泄露问题看看下面几个 demo
Demo 1:
componentWillMount: function () {
var onLogin = this.props.onLogin || function () {},
onLogout = this.props.onLogout || function () {};
this.on('authChange', function () {
console.log('user authenticated:', this.state.isAuthenticated);
return this.state.isAuthenticated
? onLogin(this.state)
: onLogout(this.state);
}.bind(this));
- 上面的例子是在 Stack Overflow 上看到的,楼主在
componentWillMount的时候挂载了authChange事件,然后 react 出现了如下的报错:
Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method”
- 意思为:我们不能在组件销毁后设置state,防止出现内存泄漏的情况
需要怎么解决啦?
componentWillUnmount: function () {
this.off('authChange', this.authChange);
this.authChange = null;
很明显这种情况就是在 dom 结构销毁的时候,事件却没有清除导致的内存泄漏,所以我们需要在componentWillUnmount的时候去清除挂载的方法
react 内存泄露相关解释和解决方法
Demo 2:
this.pwdErrorTimer = setTimeout(() => {
this.setState({
showPwdError:false
}, 1000);
设置了一个timer延迟设置state,然而在延迟的这段时间,组件已经销毁,则造成此类问题
- 解决方法:
- 利用生命周期钩子函数:componentWillUnmount
componentWillUnmount(){
clearTimeout(this.pwdErrorTimer);
clearTimeout(this.userNameErrorTimer);
如果引入了 react16.8+
文档中提到了两个重要的概念
为什么要在 effect 中返回一个函数?
- 这是 effect 可选的清除机制。每个 effect 都可以返回一个清除函数。如此可以将添加和移除订阅的逻辑放在一起。它们都属于 effect 的一部分。
React 何时清除 effect?
- React 会在组件卸载的时候执行清除操作。正如之前学到的,effect 在每次渲染的时候都会执行。这就是为什么 React 会在执行当前 effect 之前对上一个 effect 进行清除。我们稍后将讨论为什么这将助于避免 bug以及如何在遇到性能问题时跳过此行为。
如果你熟悉 React class 的生命周期函数,你可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。
关于 promise 请求是否会造成内存泄露的问题
1、Does never resolved promise cause memory leak?
2、Memory leaks in loops with Promise ?
转载自:https://juejin.cn/post/6844903812595974157
关于解决react中Can't perform a React state update on an unmounted component. This is a no-op......
备注:项目只引入了 ant-design 的部分组件,其他的组件 antd 官网有源码,可以直接复制到项目中使用,后续有时间补上全部组件。
项目使用了 antd 的自定义主题功能-->黑色,若想替换其他颜色,具体操作请查看 antd 官网
换肤(全局功能,暂时只实现了顶部导航的换肤,后续加上其他模块)
顶部导航(菜单伸缩,全屏功能)
左边菜单(增加滚动条以及适配路由的 active 操作)
UI 模块
按钮(antd 组件)
图标(antd 组件并增加彩色表情符)
加载中(antd 组件并增加顶部加载条)
通知提醒框(antd 组件)
标签页(antd 组件)
轮播图(ant 动效组件)
基础动画(animate.css 所有动画)
基础表格(antd 组件)
高级表格(antd 组件)
异步表格(数据来自掘金酱的接口)
基础表单(antd 组件)
echarts 图表
recharts 图表
登录页面(包括 GitHub 第三方登录)
404 页面
用于ReactCSS封装解决方案
为了解决css封装的问题,主要有两种方法,css-modules和css-in-js。 但是,它们两个都有很大的问题。 开发人员的体验不好,这意味着您经常需要编写比实现简单样式所期望的更多的代码。 使用react-scoped-css,您可以编写已知的普通CSS,同时具有CSS封装的优势!
它是如何工作的
将您CSS写入以.scoped.css结尾的文件中(也支持scss和sass )
/* Title.scoped.css */
. title {
background : # 999 ;
color
作为后端云服务提供商,我们在底层通过 REST API 与 WebSocket 提供数据、文件存储、短信、推送、实时消息等服务。还为各个目标平台编写了 SDK 来封装这些 API,在 SDK 中实现客户端状态的持久化,为用户提供更加符合直觉的抽象。一个有趣的现象是越来越多的平台使用的都是 JavaScript:
Web(浏览器/WebView/Windows Universal App/…)
Node.js
Electron/NW.js
React Native
Cocos2d-x(JavaScript binding)
微信小程序
为什么 SDK 要跨平台?降低成本是最为重要的一大原因
警告:不能在卸载组件上调用setState(或强迫)。这是一个无操作,但它表示应用程序中的内存泄漏。要修复,取消组件中的所有订阅和异步任务。
在Tab(由Main创建)
在组件中不同时存在挂载和更新负责回报内存泄漏,解决方法删除其中一个生命周期钩子函数...
系统: OSX 0.13.6 配置是i7 16g
最近做一个react技术栈的项目,同事搭的架子,使用的ts+react全家桶,但是每次启动项目 cpu占用高达150%。
这不是重点,因为一开始并没有注意,怎么发现的呢,启动项目之后,风扇狂转,那个声音让人有点抓狂,办公室本来挺安静的,只要一启动项目,咚咚咚咚-----那个声音太大了 ,我看monitor,cpu 占用150%。。。当...
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
in GlobalHeaderRight (a
译文:索引。警告:无法对未挂载的组件执行React状态更新。这是一个no-op,但它表明您的应用程序中存在内存泄漏。要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务。
解决方案,
1.执行start命令或者build命令内存溢出问题
.FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1.1使用的scripts脚本命令如下:
"scripts": {
"clean": "rimraf dist",
"start": "better-npm-run start",
"deploy:prod": "better-npm-run deploy:prod",
"codeco