From React Class component to Functional component with hooks

How to Add Event Listeners to React components?

Have you already added Event Listeners to the document or window objects with React.js? It is a little bit different from adding Event Listeners via the “attributes” onCLick() or onChange()… Have a look at the article below to discover how to do that!

Summary

In the example used to illustrate this article inspired by a freeCodeCamp challenge, we will display a message ‘You pressed the enter key!’ when the Enter key is pressed on the document. I have added a button to the original application in order to show that when clicking on it nothing happens. To the contrary when pressing the button with the Enter key, the message appears.
Reminder: the Enter key keycode is 13.

React and the Event Listeners

Add an Event Listener with React.js

Any event listener needed to be added for specific functionality must be attached when the component has mounted.

React provides synthetic event handlers such as onClick() we have already used on the React Simple Counter or onChange() used on the React Controlled Input – we used both of them on the React Controlled form too. This synthetic event system wraps the native one present in browsers. This means that the synthetic event system behaves exactly the same regardless of the user’s browser – even if the native events may behave differently between different browsers.

React’s synthetic event system is great to use for most interactions on DOM elements. However, any event handler attached to the document or window objects, have to be added directly using the addEventListner() method to attach an Event Listener.

We will see which hooks are the best place to attach any events depending on the fact the component is a class component or a functional component.

Remove an Event Listener with React.js

It’s good practice to clean up on React components before they are unmounted and destroyed. Removing event listeners with the removeEventListner() method is an example of one such clean up action.

We will see which hooks are the best place to remove any events depending on the fact the component is a class component or a functional component.

The Event Listeners and the React Class Components

Add an Event Listener in a React class component

In a class component the event listeners must attached via the componentDidMount() method (LifeCyle hook).

Remove an event Listener in a React class component

In a class component the event listeners must be removed via the componentWillUnMount() method (LifeCyle hook).

How to add Event Listeners in a React Class Component – an example

Steps to add Event Listeners in a React Class Component

  1. Create a class component.
  2. Add the state property message with an empty string as initial value.
  3. In the render, insert a paragraph element which displays the message.
  4. In the render, insert a button whose text is “Press Me”.
  5. Create an event handler method handleKeyPress and pass it the event as argument.
  6. Insert a condition that call a second handler method named handleEnter when the Enter key is pressed.
  7. Create the handleEnter method which modify the state message value. The string ‘You pressed the enter key!’ must be added to the previous state.
  8. Do not forget to bind the two methods!
  9. Attach the event listener to the document via the componentDidMount() method. Pass the addEventListener() method two arguments: the event ‘keydown’ in this example and the handler method handleKeyPress.
  10. Do not forget to clean up the component by removing the same event listener with the removeEventListener() method via the componentWillUnmount() method.

The final code to add Event Listeners in a React Class Component

JS (React)
class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            message: “”
        };
        this.handleEnter = this.handleEnter.bind(this);
        this.handleKeyPress = this.handleKeyPress.bind(this);
    }
    componentDidMount() {
        document.addEventListener(“keydown”, this.handleKeyPress);
    }
    componentWillUnmount() {
        document.removeEventListener(“keydown”, this.handleKeyPress);
    }
    handleEnter() {
        this.setState((state) => ({
            message: state.message + ‘You pressed the enter key! ‘
        }));
    }
    handleKeyPress(event) {
        if (event.keyCode === 13) {
            this.handleEnter();
        }
    }
    render() {
        return (
            <div>
                <p>{this.state.message}</p>
                <button>Click me!</button>
            </div>
        );
    }
}
ReactDOM.render(<MyComponent />, document.getElementById(‘event-listeners’));

Test the final code in the below pen by pressing the enter key in the document.

See the Pen
React tricks: Add Event Listeners in a class component
by Coding-Tricks (@coding-tricks)
on CodePen.

The Event Listeners and the React Functional Components

Add an Event Listener in a React functional component

In a functional component the event listeners must attached via the useEffect() hook which replace the componentDidMount and componentDidUpdate lifecycle methods.

Remark: If the array of dependency is void, the event listener will be attached only at the first rendering. As a result, the message will appear once only even if the user press the enter key many times. If there is no array of dependency, the message will appear as many times the enter is pressed.

Remove an event Listener in a React functional component

In a functional component the event listeners must be removed via the cleanup function placed at the bottom of the useEffect() hook.

Finally, the event handlers, the added event listener and the removed event listener are all included in the place, the useEffect() hook.

How to add Event Listeners in a React Functional Component – an example

The below code is inspired by an article written by Bobby Hadz.

Steps to add Event Listeners in a React Functional Component

  1. Create a functional component.
  2. Add the state property message with an empty string as initial value.In the render, insert a <p> element which display the message.
  3. In the render, insert a <button> whose text is “Press Me”.
  4. In the useEffect() hook, create an event handler function handleKeyPress and pass it the event as argument.
  5. Insert a condition that call a second handler function named handleEnter when the Enter key is pressed.
  6. In the useEffect() hook, create the handleEnter function which modify the state message value. The string ‘You pressed the enter key!’ must be added to the previous state.
  7. In the useEffect() hook, attach the event listener to the document via the addEventListener() method. Pass it two arguments: the event ‘keydown’ in this example and the handler method handleKeyPress.
  8. In the useEffect() hook, do not forget to clean up the component by removing the same event listener with the removeEventListener() method via the return function.

The final code to add Event Listeners in a React Functional Component

JS (React)
import { useState, useEffect } from ‘react’;
const MyListenedApp = () => {
    const [message, setMessage] = useState(“”);
    useEffect(() => {
        const handleEnter = () => {
            setMessage(message + “You pressed the enter key. “);
        };
        const handleKeyPress = (event) => {
            if (event.keyCode === 13) {
                handleEnter();
            }
        };
        document.addEventListener(‘keydown’, handleKeyPress);
        return  () => {
            document.removeEventListener(‘keydown’, handleKeyPress);
        };
    });
    return (
        <div>
            <h1>{message}</h1>
            <button>Press me!</button>
        </div>
    );
}
ReactDOM.render(<MyListenedApp />, document.getElementById(‘event-listeners’));

Test the final code in the below pen by pressing the enter key in the document.

Modify the pen to test with and without the array of dependency in the useEffect hook.

See the Pen
React tricks: Add Event Listeners with the hooks useState, useEffect and useRef
by Coding-Tricks (@coding-tricks)
on CodePen.

In conclusion

In this article, we have discovered how to add event listeners to the document or window objects. We are able to attach and remove event listeners on both class and functional React components, now.

In a next article, we will try to optimize re-renders via shouldComponentUpdate() and React.memo().

Haut de page