Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove Event Listener On Unmount React

I had higher order component in react like this:

export default function (InnerComponent) {     class InfiniteScrolling extends React.Component {          constructor(props){             super(props);         }          componentDidMount() {             window.addEventListener('scroll', this.onScroll.bind(this), false);         }          componentWillUnmount() {             window.removeEventListener('scroll', this.onScroll.bind(this), false);         }          onScroll() {             if ((window.innerHeight + window.scrollY) >= (document.body.offsetHeight - 50)) {                 const { scrollFunc } = this.props;                 scrollFunc();             }         }          render() {             return <InnerComponent {...this.props} />;         }     }      InfiniteScrolling.propTypes = {         scrollFunc: PropTypes.func.isRequired     };      return InfiniteScrolling; } 

After unmounting the component which are been wrapped via InfiniteScrolling, they where still throwing the error like (when I did scrolling):

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.

Even though I did remove the scroll event on my component unmount. It didn't work.

But when I changed the code to like this:

constructor(props){     super(props);     this.onScroll = this.onScroll.bind(this); }  componentDidMount() {     window.addEventListener('scroll', this.onScroll, false); }  componentWillUnmount() {     window.removeEventListener('scroll', this.onScroll, false); } 

everything seems to be working fine, without any issues.

I feel they are exactly the same thing, but the second one works fine while the first one was throwing up the error in the console as mentioned before!

like image 561
Ant's Avatar asked Jul 25 '16 09:07

Ant's


People also ask

Does React remove event listener on unmount?

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.

How do I remove an event listener?

The removeEventListener() is an inbuilt function in JavaScript which removes an event handler from an element for a attached event. for example, if a button is disabled after one click you can use removeEventListener() to remove a click event listener.

How do I remove an event listener from a React component?

The removeEventListener call must reference the exact same function in the removeEventListener call to remove the listener correctly. If you're not using React hooks, you can use the class-based React component lifecycle methods instead.

How to clean up a React component when it is unmounted?

Note that the cleanupListener function that the React.useEffect callback can returns will be called at the time that this React component is unmounted and is the place to do cleanup. This happens via window.removeEventListener.

How to add a listener to a mounted component?

A common and simple use case is to add a listener after the initial mount and remove it when the component unmounts. This can be done with the useEffect hook. ❗️Don't forget the second parameter [] when calling useEffect.

How do I add an event listener to a window?

If you want to add an event listener to the window, or document objects, use the same approach, excluding the ref. We passed an empty dependencies array to the useEffect hook, so it's only going to run when the component mounts. We only want to call the addEventListener method once - when the component mounts.


2 Answers

.bind always creates a new function so you need to do like below, so it adds and removes the same function.

    constructor(props){         super(props);         this.onScroll = this.onScroll.bind(this); //bind function once     }      componentDidMount() {         window.addEventListener('scroll', this.onScroll, false);     }      componentWillUnmount() {         // you need to unbind the same listener that was binded.         window.removeEventListener('scroll', this.onScroll, false);     } 
like image 188
Yury Tarabanko Avatar answered Oct 13 '22 08:10

Yury Tarabanko


      componentDidMount() {             window.addEventListener('scroll', this.onScroll, false);         }          componentWillUnmount() {             window.removeEventListener('scroll', this.onScroll, false);         }         // use arrow function instead         onScroll = () => {              if ((window.innerHeight + window.scrollY) >= (document.body.offsetHeight - 50)) {                 const { scrollFunc } = this.props;                 scrollFunc();             }         } 

or you can use Arrow functions , to solve .bind(this) problems it worked form just fine.

like image 43
The pyramid Avatar answered Oct 13 '22 10:10

The pyramid