setState(…): Can only update a mounted or mounting component. This usually means you called setState

1.遇到的八阿哥:

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the undefined component.

2.招来八阿哥的骚操作:

componentDidMount() {
    window.addEventListener('resize', this.reComputeHeight.bind(this));
}
reComputeHeight = () => {
    this.setState({
      tableHeight: document.body.clientHeight - 450,
    });
}

在componentDidMount生命周期中监听了resize,监听函数调用了setState,setState必须在组件确定渲染完成的情况下调用,而监听函数虽然在componentDidMount中声明,而监听的回调却可能发生在其他生命周期时。

//所以要做的第一步补救就是,当组件被卸载时,销毁对resize的监听
componentWillUnmount() {
 window.removeEventListener('resize', this.reComputeHeight.bind(this));
}

这么做是可以解决一部分人的问题了,但是如果你不止一个组件做了监听,那么在两个都加了监听的组件间切换还是会报错。这里其实我不是很理解,按道理讲一个组件在卸载时将监听都移除了,新组件被渲染时重新添加监听,互不影响,推测组件1的componentWillUnmount还未执行完,组件2的componentDidMount就已经执行了?不是串行的咩???
不管怎样机智的我还是找到了干掉报错的方法

//当执行setState前检查下是否已经可以取到一个DOM,如果可以则证明组件渲染完成了

 /*
     取DOM的方法,react提供了三种。
     1. 第一个字符串方法,简单但是被废弃了
     2. 第二个回调方法,看着就麻烦不想用
     3. 第三个createRef方法,简单但是要react@16.3版本才支持
 */

//坑爹的事出现了,我们项目目前是依赖react@15.6,我会为了解决一个报错而去做升级版本库的蠢事???...我做了==

/*
    升级的react相关库:
    "react": "^16.4.2",
    "react-dom": "^16.4.2",
    "react-redux": "^5.0.7",
    "react-router-dom": "^4.3.1",
*/
//其实还有几个相关库没升级,升级会导致新的报错,心累了,拖鞋...
//升级完终于可以用我喜欢的方法了!完全版代码!

componentDidMount() {
  //组件渲染完成,添加监听
  window.addEventListener('resize', this.reComputeHeight.bind(this));
}
componentWillUnmount() {
  //组件卸载,移除监听
  window.removeEventListener('resize', this.reComputeHeight.bind(this));
}
//获取DOM
myRef = React.createRef();
reComputeHeight = () => {
  if (this.myRef.current) {//若DOM存在,执行setState
    this.setState({
      tableHeight: document.body.clientHeight - 450,
    });
  }
}
<div ref={this.myRef} >我是一个随便的DOM,能娶到我说明你的组件渲染成功了</div>

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值