Article Logo Go Back

Always Throw Away Your Event Listeners

AvatarMay 7, 201925 minsTim Ellenberger

Unlike your React components, the event listeners they've created don't magically disappear after their UI unmounts from the DOM. Undisposed event listeners will linger in your browser to haunt future components. Be afraid.

For example, let's say you want to create a simple component that displays the instantaneous window width.

The first step is to create a function for setting some component state we'll call windowWidth, then create a window event listener in the React lifecycle method componentDidMount() with our new setter function as a callback.

1state = {2  windowWidth: null3};45componentDidMount() {6  // Measure the initial screen width7  this.updateWindowSize();89  // If the screen width changes, update component state10  window.addEventListener('resize', this.updateWindowSize);11}1213updateWindowSize = () =>14  this.setState({15    windowWidth: window.innerWidth16  });

When the component first mounts, updateWindowSize() is called directly. As the window size changes, the event listener we've created calls the same function as a callback.

Before the current component unmounts, our event listener must be removed from the global Window object by utilizing the React lifecycle method componentWillUnmount().

All together the code is quite simple and can save you from a lot of potential headaches.

🎉 Your window width is px 🎉

componentsWindowSizeReporter.jsjsx
1import React from 'react';23class WindowSizeReporter extends React.Component {4  state = {5    windowWidth: null6  };78  componentDidMount() {9    // Measure the initial screen width10    this.updateWindowSize();1112    // If the screen width changes, update component state13    window.addEventListener('resize', this.updateWindowSize);14  }1516  componentWillUnmount() {17    // Remove resize event listener from window18    window.removeEventListener('resize', this.updateWindowSize);19  }2021  updateWindowSize = () =>22    this.setState({23      windowWidth: window.innerWidth24    });2526  render() {27    const { windowWidth } = this.state;2829    return <span>Your window width is {windowWidth}</span>;30  }31}3233export default WindowSizeReporter;

Need a developer? Drop me a line!

Bug?
Edit Post