简体   繁体   中英

React - Warning: Can't call setState (or forceUpdate) on an unmounted component

Im getting the below error from several components in my application.

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.

One of the components that is causing this has a resize remove event listener in the componentWillUnmount method. How do I resolve this issue. From what I have seen in online examples it is common to unsubscribe from event in this method.

I am not allowed to paste specific code so I am writing psudo code

clickHandler() {
  this.setState({ opened: !(this.state.opened) });
}

componentDidMount() {
   this.setState({ width: window.innerWidth } );
   window.addEventListener('resize', this.updateWidth);
}

componentWillUnmount() {
    window.removeEventListener('resize', this.updateWidth);
}

private updateWidth() {
     if (this.state.opened &&
         window.innerWidth >= someMethodReturnsViewportConstant()) {

         this.onClickHandler();
         const htmlElement: HTMLInputElement =
             document.querySelector('#html-element-id');
         if (htmlElement && htmlElement) {
             htmlElement = false;
         }
     }
}

What I have done:

I have read all the posts on Stack about this and none of them explained why my code is causing this.

Since you haven't shared much code so I assume below is what you are doing

this.updateWidth = setTimeout(() => {
   this.setState({
      width:100
   });
}, 3000);

componentWillUnmount() {
    clearTimeout(this.updateWidth);
}

So wherever you do seState in setTimeout clear them in componentWillUnMount like I mentioned

Also if you are using componentWillReceiveProps or componentDidUpdate you need to check current props or state with nextProps or nextState if they are not equal then do setState. This check is mandatory. The is also the reason for the infinite warning you are facing

As others have said, you haven't provided enough code to see what's actually going on.

What you can do, however, is add a flag to see if your component has been unmounted or not, preventing state updates.

Here's an example.

class ExampleComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      exampleState: []
    };
    this.isUnmounted = false;
    this.updateState = this.updateState.bind(this);
  }

  componentWillUnmount() {
    this.isUnmounted = true;
  }

  updateState() {
    if (!this.isUnmounted) { // Don't allow state change if component is unmounted
      this.setState({ exampleState: [1, 2, 3] });
    }
  }
}

Now you have a flag that you can debug your state change with. Do a check in your components state changes one by one and eventually you will find where the warning is coming from.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM