react里这种报错该怎么解决

报错提示如下:

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 Timer component.

这里是我的代码(这里的props是接受另外一个组建传过来的数据):

class Timer extends PureComponent {

    static propTypes = {
        aim: PropTypes.number

    };
    constructor(props) {
        super(props);
        this.state = {
            num: 0,
            days: 0
        }
    }
    tick() {
        if (this.props.aim) {
            const aimTime = new Date(this.props.aim);
            const currentTime = Date.parse(new Date());
            const leftTime = aimTime - currentTime;
            const day = aimTime.getDate();
            const hours = aimTime.getHours();
            this.setState({
                num: hours,
                days: day
            }, () => {
                if (currentTime === this.props.aim) {
                    clearInterval(this.interval);
                }
            });
        }else{
            this.setState({
                num: 0,
                days: 0
            })
        }
    }
    componentDidMount() {
        this.interval = setInterval(() => this.tick(), 1000);
    }
    componentWillMount(){
       clearInterval(this.interval);
        
    }
    render() {

        return (
            <span>还剩 {this.state.days} 天 {this.state.num} 小时</span>
        );
    }
}

这里附上stackflow里的答案,但是看了下不是很清楚。点击链接

阅读 7.3k
6 个回答

在componentWillUnmount生命周期把你这个定时器clear掉

谢邀!
首先恭喜您已经解决了!在忙着重构react没来得及看,真是抱歉!我就说说原因吧!

一般原因

这种错误一般出现在我们已经从DOM中移除了react组件,这时才调用setState改变组件的状态

举个比较常见的例子:我们在componentWillMount中发送异步请求,并且我们调用setState根据响应数据改变组件的状态,然后请求还未完成,我们改变了页面也就是移除该组件,就会报这个错误。这是因为虽然组件已经被移除,但是请求还在执行,所以会报setState() on an unmounted component的错误

如何解决?

我们只要在react组件被移除之前终止setState操作就可以了。

业务例子

  1. 定时器,在生命周期函数componentWillUnmount把定时器清除掉。
  2. 异步请求,用abort()包裹Promise等 ,请求方式不一样,处理方法也不同!

你的报错信息是 setstate 只能更新已经渲染的或者正在渲染的组件,你可能在已经注销的组建上应用了setstate方法
问题可能就是你的组件生命周期已经结束的情况下this.setinterval继续在执行。所以建议你这么处理

componentWillUnmount(){
    clearInterval(this.interval);
}

就问题来说,是由于组件 mount 之前就改变了 state,因此这是一个无效操作。
而 so 上面答案描述的是用与操作符做一个可行性判断,也就是确认语句在符合条件以后再执行。

对于你的代码,在 componentWillMount 里消除了定时器,而在 componentDidMount 里又注册了一个定时器,因此这个定时器全局存在,那么当这个组件被卸载的时候,这个定时器依然存在,里面的代码依然运行,这时候 this 指向的就是一个未渲染的组件了。所以会有这个 warning。

因此,采用 so 中的解决方案,你可以在 componentWillUnmount 中将这个定时器注销掉,那么组件卸载后这个定时器也就不存在了。即不会产生 warning,也不会浪费性能。

谢邀 ,
这个肯定涉及到生命周期
在componentWillMount中发送异步请求(未完成情况下),调用setState根据响应数据改变组件的状态 移除了组件但请求没有中断 /
所以就会报错

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题