Can’t perform a React state update on an unmounted component

Can’t perform a React state update on an unmounted component

蚊子前端博客
发布于 2019-06-03 18:03
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

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

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

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

COPYJAVASCRIPT

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 = 'https://www.xiabingbao.com/post/react/jump-setstate.html#/' + 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()方法中进行判断,若可以跳转,则直接不渲染;

COPYJAVASCRIPT

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 = 'https://www.xiabingbao.com/post/react/jump-setstate.html#/' + jumpUrl; window.sessionStorage.setItem('targetJump', '1'); return null; } return (
); }
  1. 使用高阶组件重新封装 componentWillUnmount 和 setState;

COPYJAVASCRIPT

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
标签:

阅读(3137)

公众号:

qrcode

微信公众号:前端小茶馆

版权声明:
作者:Joker 链接:https://hooper.eu.org/archives/47630
文章版权归作者所有,转载请注明出处。
THE END
分享
二维码
打赏
< <上一篇
下一篇>>