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!
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.
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.
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.
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.
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.
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.
.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); }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With