鍍金池/ 問答/HTML/ react里這種報(bào)錯(cuò)該怎么解決

react里這種報(bào)錯(cuò)該怎么解決

報(bào)錯(cuò)提示如下:

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是接受另外一個(gè)組建傳過來的數(shù)據(jù)):

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} 小時(shí)</span>
        );
    }
}

這里附上stackflow里的答案,但是看了下不是很清楚。點(diǎn)擊鏈接

回答
編輯回答
菊外人

//...= =

2018年7月30日 19:19
編輯回答
涼薄

你的報(bào)錯(cuò)信息是 setstate 只能更新已經(jīng)渲染的或者正在渲染的組件,你可能在已經(jīng)注銷的組建上應(yīng)用了setstate方法。
問題可能就是你的組件生命周期已經(jīng)結(jié)束的情況下this.setinterval繼續(xù)在執(zhí)行。所以建議你這么處理

componentWillUnmount(){
    clearInterval(this.interval);
}
2017年4月28日 10:01
編輯回答
何蘇葉

在componentWillUnmount生命周期把你這個(gè)定時(shí)器clear掉

2018年1月19日 00:05
編輯回答
別傷我

就問題來說,是由于組件 mount 之前就改變了 state,因此這是一個(gè)無效操作。
而 so 上面答案描述的是用與操作符做一個(gè)可行性判斷,也就是確認(rèn)語句在符合條件以后再執(zhí)行。

對于你的代碼,在 componentWillMount 里消除了定時(shí)器,而在 componentDidMount 里又注冊了一個(gè)定時(shí)器,因此這個(gè)定時(shí)器全局存在,那么當(dāng)這個(gè)組件被卸載的時(shí)候,這個(gè)定時(shí)器依然存在,里面的代碼依然運(yùn)行,這時(shí)候 this 指向的就是一個(gè)未渲染的組件了。所以會(huì)有這個(gè) warning。

因此,采用 so 中的解決方案,你可以在 componentWillUnmount 中將這個(gè)定時(shí)器注銷掉,那么組件卸載后這個(gè)定時(shí)器也就不存在了。即不會(huì)產(chǎn)生 warning,也不會(huì)浪費(fèi)性能。

2017年8月5日 10:50
編輯回答
執(zhí)念

謝邀 ,
這個(gè)肯定涉及到生命周期
在componentWillMount中發(fā)送異步請求(未完成情況下),調(diào)用setState根據(jù)響應(yīng)數(shù)據(jù)改變組件的狀態(tài) 移除了組件但請求沒有中斷 /
所以就會(huì)報(bào)錯(cuò)

2018年7月13日 14:49
編輯回答
不二心

謝邀!
首先恭喜您已經(jīng)解決了!在忙著重構(gòu)react沒來得及看,真是抱歉!我就說說原因吧!

一般原因

這種錯(cuò)誤一般出現(xiàn)在我們已經(jīng)從DOM中移除了react組件,這時(shí)才調(diào)用setState改變組件的狀態(tài)

舉個(gè)比較常見的例子:我們在componentWillMount中發(fā)送異步請求,并且我們調(diào)用setState根據(jù)響應(yīng)數(shù)據(jù)改變組件的狀態(tài),然后請求還未完成,我們改變了頁面也就是移除該組件,就會(huì)報(bào)這個(gè)錯(cuò)誤。這是因?yàn)殡m然組件已經(jīng)被移除,但是請求還在執(zhí)行,所以會(huì)報(bào)setState() on an unmounted component的錯(cuò)誤

如何解決?

我們只要在react組件被移除之前終止setState操作就可以了。

業(yè)務(wù)例子

  1. 定時(shí)器,在生命周期函數(shù)componentWillUnmount把定時(shí)器清除掉。
  2. 異步請求,用abort()包裹Promise等 ,請求方式不一樣,處理方法也不同!
2018年2月15日 05:51