惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
MongoDB | Blog
MongoDB | Blog
博客园_首页
博客园 - 三生石上(FineUI控件)
博客园 - 聂微东
B
Blog RSS Feed
D
Docker
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
Recent Announcements
Recent Announcements
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
A
About on SuperTechFans
The GitHub Blog
The GitHub Blog
G
Google Developers Blog
V
V2EX
量子位
雷峰网
雷峰网
月光博客
月光博客
云风的 BLOG
云风的 BLOG
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Tailwind CSS Blog

蚊子的前端博客

微说 | 有的人觉得只要不考XX,一定能考好!-蚊子的前端博客 微说 | 春天来了-蚊子的前端博客 明天和意外不知道哪个先来-蚊子的前端博客 微说 | 既然错过了路口,就及时止损,重新规划路线上路-蚊子的前端博客 微说 | 2025年的出生人口数是792万-蚊子的前端博客 微说 | 工作年终总结,让写对接的接口的数量?-蚊子的前端博客 微说 | 温家宝:没有政治体制改革的成功 经济体制改革不可能进行到底-蚊子的前端博客 微说 | 违法犯罪了该不该被禁言?-蚊子的前端博客 微说 | 不明白为什么在推荐去俄罗斯旅游-蚊子的前端博客 微说 | 易中天论骗子-蚊子的前端博客 微说 | 一场大风吹散了秋天-蚊子的前端博客 微说 | 既要、又要、还要、更要!-蚊子的前端博客 又是一年的国庆雨季-蚊子的前端博客 微说 | 预估下2025年的出生人口数据-蚊子的前端博客 微说 | 可惜了我那些小时候的书本-蚊子的前端博客 微说 | 牛马有的是,驴不够了!-蚊子的前端博客 微说 | 能否有一条非户口也能高考的路-蚊子的前端博客 微说 | 小聊中医-蚊子的前端博客 微说 | 将要制作的一款新产品-蚊子的前端博客 微说 | 做人要有信-蚊子的前端博客 微说 | 好一个正义联盟-蚊子的前端博客 微说 | 都是见过吃过的主儿-蚊子的前端博客 微说 | 追求8小时工作制有错吗?-蚊子的前端博客 微说 | 如果尖锐的批评完全消失-蚊子的前端博客 微说 | 很好!-蚊子的前端博客 微说 | 封禁用户可以,但要告知具体原因-蚊子的前端博客 微说 | 面朝大海,春暖花开-蚊子的前端博客 微说 | 程序员的悲哀是什么?-蚊子的前端博客 微说 | 2025年出生人口的预测-蚊子的前端博客 前端在 LiveKit 中如何获取所有的参与者-蚊子的前端博客
Can’t perform a React state update on an unmounted compon...
author · 2019-06-03 · via 蚊子的前端博客

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 t

最近项目中有一个这样的需求,从别的项目要转到我项目中的某个页面,不过回退时要可以回退到项目的首页。

实现这样的跳转的话,应当是首先要跳转到项目的首页,然后再从首页跳转到对应的页面。

我最开始的实现是这样的:

componentDidMount() {
    const jumpUrlList = ['own'];
    const jumpUrl = getQueryString('jumpto');
    const targetJump = window.sessionStorage && window.sessionStorage.getItem('targetJump');

    // 防止无限跳转,使用sessionStorage存储一个标记,整个周期内只跳转一次
    if (jumpUrlList.indexOf(jumpUrl) > -1 && !targetJump) {
        window.location.href = '#/' + jumpUrl;
        window.sessionStorage.setItem('targetJump', '1');
    }
}

但运行时,会提示这个错误:

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 the componentWillUnmount method.

意思是:无法对没有实例的组件进行响应状态更新。您可以在 componentWillUnmount 方法中取消所有的订阅和异步任务。

因为我在首页中有异步请求,请求返回回来后,使用setState更新视图。但我已经跳转到别的路由了,导致 setState 更新时,当前组件已被销毁了,无法更新。

解决方法:

  1. 若您的异步请求可以取消的话,在 componentWillUnmount 中取消请求;
  2. render()方法中进行判断,若可以跳转,则直接不渲染;
render() {
    const jumpUrlList = ['own'];
    const jumpUrl = getQueryString('jumpto');
    const targetJump = window.sessionStorage && window.sessionStorage.getItem('targetJump');
    if (jumpUrlList.indexOf(jumpUrl) > -1 && !targetJump) {
        window.location.href = '#/' + jumpUrl;
        window.sessionStorage.setItem('targetJump', '1');
        return null;
    }

    return (
        <div className="home">
            <User />
        </div>
    );
}
  1. 使用高阶组件重新封装 componentWillUnmount 和 setState;
function inject_unount(target) {
    // 改装componentWillUnmount,销毁的时候记录一下
    let next = target.prototype.componentWillUnmount;
    target.prototype.componentWillUnmount = function() {
        if (next) next.call(this, ...arguments);
        this.unmount = true;
    };
    // 对setState的改装,setState查看目前是否已经销毁
    let setState = target.prototype.setState;
    target.prototype.setState = function() {
        if (this.unmount) return;
        setState.call(this, ...arguments);
    };
}
@inject_unount
class BaseComponent extends Component {}
//以后我们写组件时直接继承BaseComponent