Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React how to remove listners correctly in componentWillUnmount, why do I need the bind in the constructor?

I'm a bit confused, what is the difference between this sintax:

  constructor(props) {
    super(props);
    this.state = {
      openPane: false
    }
    this.togglePaneHelper = this.togglePaneHelper.bind(this);
  }
  componentDidMount() {
    document.body.addEventListener('click', this.togglePaneHelper);
  }
  componentWillUnmount() {
    document.body.removeEventListener('click', this.togglePaneHelper);
  }

and this one:

  constructor(props) {
    super(props);
    this.state = {
      openPane: false
    }
  }
  componentDidMount() {
    document.body.addEventListener('click', this.togglePaneHelper.bind(this));
  }
  componentWillUnmount() {
    document.body.removeEventListener('click', this.togglePaneHelper);
  }

My concern is that the second syntax isn't removing correctly the listner and it cause this warning:

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.
like image 464
daniele bertella Avatar asked Feb 05 '16 12:02

daniele bertella


1 Answers

IMPORTANT:

a.bind(this) !== a.bind(this) 

According to MDN:

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

Your first approach overrides this.togglePaneHelper with new, bound function. Second one removes different event listener function than it was added - both addEventListener and removeEventListener have to get the same reference of function.

like image 82
Radosław Miernik Avatar answered Sep 28 '22 00:09

Radosław Miernik