Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing event listener in React (lodash.throttle)

removeEventListener() works when I don't use throttle() from lodash.

   window.addEventListener('scroll', this.checkVisible, 1000, false);
     window.removeEventListener('scroll', this.checkVisible, 1000, false);

(I bound the method in the constructor)


Unfortunately, with the throttle(this.checkVisible) function wrapped around it - doesn't work. I assume it's because when trying to remove the listener, throttle() makes new instance and maybe I should bind it globally. How though (if that's the case)?

  import React from 'react';
    import throttle from 'lodash.throttle';
    
    class About extends React.Component {
      constructor(props) {
        super(props);
    
        this.checkVisible = this.checkVisible.bind(this);
      }
    
      componentDidMount() {
        window.addEventListener('scroll', throttle(this.checkVisible, 1000), false);
    
      }
    
      checkVisible() {
       if (window.scrollY > 450) {
        // do something
        window.removeEventListener('scroll', throttle(this.checkVisible, 1000),
        false);
        }
      }
    
      render() {
        return (
          <section id="about"> something
          </section>
        );
      }
    }
    
    export default About;
like image 221
Sebastian Avatar asked Oct 29 '17 16:10

Sebastian


People also ask

How do I remove event listener in React?

Add the event listener in the useEffect hook. Return a function from the useEffect hook. Use the removeEventListener method to remove the event listener when the component unmounts.

Does removing an element remove event listeners?

In modern browsers, if a DOM Element is removed, its listeners are also removed from memory in javascript. Note that this will happen ONLY if the element is reference-free. Or in other words, it doesn't have any reference and can be garbage collected. Only then its event listeners will be removed from memory.

Why should you remove event listeners once they are no longer used?

The event listeners need to be removed due to following reason. Avoid memory leaks, if the browser is not handled it properly. Modern browsers will garbage collect event handlers of removed DOM elements but it is not true in cases of legacy browses like IE which will create memory leaks.

Can you remove event listeners?

Event listeners can also be removed by passing an AbortSignal to an addEventListener() and then later calling abort() on the controller owning the signal.


1 Answers

Lodash trottle creates a throttled function so you need to store a reference to it in order to remove the eventlistener.

import React from 'react';
import throttle from 'lodash.throttle';

class About extends React.Component {
  constructor(props) {
    super(props);

    this.checkVisible = this.checkVisible.bind(this);
    // Store a reference to the throttled function
    this.trottledFunction = throttle(this.checkVisible, 1000);
  }

  componentDidMount() {
    // Use reference to function created by lodash throttle
    window.addEventListener('scroll', this.trottledFunction, false);

  }

  checkVisible() {
   if (window.scrollY > 450) {
    // do something
    window.removeEventListener('scroll', this.trottledFunction, false);
    }
  }

  render() {
    return (
      <section id="about"> something
      </section>
    );
  }
}

export default About;
like image 138
lagerone Avatar answered Sep 21 '22 10:09

lagerone