簡體   English   中英

無法在已卸載的組件上調用setState(或forceUpdate)。 應對

[英]Can't call setState (or forceUpdate) on an unmounted component. React

Gutentag,伙計們!

卸載組件后,我不斷從應用程序中收到此錯誤消息:

Warning: Can't call setState (or forceUpdate) 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.
    in Header (at index.js:27)

現在,這里是Header組件的代碼:

class Header extends Component {
  isCancelled = false;
  state = {
    someStateVars: x,
    separateColumns: 'true',
  }

  handleChange = (event) => {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

    if (!this.isCancelled) {
      this.setState({ //######THIS IS LINE 27######
        [name]: value
      });
    }
  }

  handleDisplayChange = (event) => {
    const value = event.target.value;
    const name = 'separateColumns';

    if (!this.isCancelled) {
      this.setState({  
        [name]: value
      }, () => {
        this.props.displayChange();
      });
    }
  }

  serversRefresh = () => {

    if (!this.isCancelled) {
      setTimeout(() => {
        this.setState({refreshed: false});
      }, localStorage.getItem('seconds')*1000); //disable refresh for 15 seconds
    }
  }

  reactivateButton = () => {
    if (!this.isCancelled) this.setState({refreshed: false});
  }

  componentDidMount() {
    if(localStorage.getItem('seconds')>5 && !this.isCancelled){
      this.setState({refreshed: true});
    }
  }

  componentWillUnmount() {
    this.isCancelled = true;
  }
}

當我看到此錯誤時,我添加了isCancelled變量,該變量在componentWillUnmount()函數中更改為true。

卸載Header組件后,15秒鍾后,重新激活serversRefreshbutton時,出現此錯誤消息。

我該如何解決?

在遇到此問題的另一個組件上,“ isCancelled” var確實起到了幫助,但是在這里我看到它沒有任何影響,問題仍然存在。

只需將超時存儲在變量中,例如

this.timeout = setTimeout(/* your actions here*/, /* your timeout */)

然后在componentWillUnmount清除超時

componentWillUnmount() {
    clearTimeout(this.timeout)
}

它應該解決您的問題,而不會像this.isCancelled這樣this.isCancelled 檢測組件的安裝狀態是無操作的,因為即使卸載后它仍會從內存中卸載。

setTimeout返回計時器的ID,以后可以使用該ID取消。 clearTimeout通過其ID取消超時(如果尚未執行)。

有關您的案例的更多信息,您可以在這里閱讀: 為什么isMounted是antipattern

有關MDN上的計時器的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM