Guide to React Event Management

Introduction

Events usually represent some type of interaction between the user and the app - any time a user clicks on the object, types in the input field, drag or drop some element, and so on. Therefore, each event usually requires some type of reaction from the app. Each time a significant event occurs, we, as programmers, can define a function used to respond to the occurred event. Those functions are called event handlers, and they are the core of event management in any programming language. Event management is a set of techniques used to handle events.

React is no different! In this guide, we'll be digging deeper into the concept of event management in React. We'll take a look at several different types of events, as well as mechanisms used to handle those events.

Differences Between DOM and React Event Handling

If you are using React, you are probably already familiar with DOM events in JavaScript:

<!- JavaScript event ->
<button onclick="handleClick()">
    Trigger Function
</button>

This is the onclick DOM event. When this example button is clicked the handleClick() function is called - that's the basic principle of the event management. That basic idea is shared between JavaScript and React, but there are a couple of nuances differentiating the two of them.

First of all, there is a minor difference in the event naming - React uses camel case names instead of lowercase names used by JavaScript. After a quick look at the previous example, you will notice the name of the event is onclick, and the React alternative is onClick. Furthermore, React makes use of JSX (JavaScript XML), which allows us to pass a function as the event handler (inside curly braces) rather than a string:

<!- React event ->
<button onClick={handleClick}>
    Trigger Function
</button>

Note how we didn't call the handleClick function inside curly brackets - calling it by {handleClick()} will call the handler function each time an element is rendered. The syntax we've used ensures the handler function is called only when the event is registered.

Oftentimes you'll find yourself in the situation where you want to prevent the default behavior after the event is registered. For example, the onsubmit JavaScript event is registered after a user clicks the submit button. The default behavior is to send form data appropriately and reload the web page, but we might need to prevent reloading the page. JavaScript has a handy trick for preventing the default behavior up in its sleeve:

<form onsubmit="console.log('You clicked submit.'); return false">
    <button type="submit">Submit</button>
</form>

We've defined the handler function in the usual way, but notice how we've added return false after the handler function definition. That's the way JavaScript developers prevent the default behavior when handling events. If you don't put return false after the handler function in this example, the page will reload before the console even gets a chance to log the message.

Note: An event handler function can be defined in a JavaScript file, and called in HTML when an event is detected. Alternatively, you can also define and call the handler function directly in HTML code (as you can see in the example above).

React simply doesn't support this trick! To prevent default behavior in React, you must explicitly call preventDefault:

function Form() {
    function handleSubmit(e) {
        e.preventDefault();
        console.log("You clicked submit.");
    }

    return (
        <form onSubmit={handleSubmit}>
            <button type="submit">Submit</button>
        </form>
    );
}

Maybe not as simple as event handling in JavaScript, but certainly a more robust way to handle events. This example illustrates the event handling in use with a functional component in React. We've simply declared a handler function in the component, and called it within the return() method.

Note: React takes care of the cross-browser compatibility, so you don't need to worry about that!

Handling Events in Functional Components

The event handler is passed as an attribute to an element or component in a functional component. When the user interacts with the element, this attribute receives a function that describes what happens.

Handling onClick Event

If the user clicks the element multiple times, the onClick event is triggered and the function is called multiple times, just like any other event. Let’s see how this looks in practice, we would create a button and call a function:

const App = () => {
    const handleClick = () => {
        console.log("This function has been triggered!");
    };

    return (
        <div className="App">
            <h1>Hello World</h1>
            <button onClick={handleClick}>Trigger Function</button>
        </div>
    );
};

This will log out “This function has been triggered!” in the console.

Passing Parameters Into Events

If we want to pass parameters or values to the function that is being triggered, we must use an arrow function or an actual function. In our case, let’s say we want to pass a value to the function and then log it in the console:

const App = () => {
    const handleClick = (name) => {
        console.log("My Name is:", name);
    };
    return (
        <div className="App">
            <h1>Hello World</h1>
            <button onClick={() => handleClick("John Doe")}>
                Trigger Function
            </button>
        </div>
    );
};

This will display “My Name is: John Doe” in the console. We can also make use of an actual function using the function keyword and everything will still work perfectly:

<button onClick={function(){handleClick('John Doe')}}>Trigger Function</button>

Handling onSubmit Event

We can also handle form submit events with React when a user clicks the submit button or taps the enter key on the keyboard. This is handled similarly to the onClick event:

const App = () => {
    const handleSubmit = () => {
        console.log("The submit button was clicked!");
    };

    return (
        <div className="App">
            <h1>Hello World</h1>
            <form onSubmit={handleSubmit}>
                <label>Name</label>
                <input type="text" />
                <button type="submit">Submit</button>
            </form>
        </div>
    );
};

"The submit button was clicked!" will be logged out as a result of this. However, because the browser will immediately reload, we will use the preventDefault() method to prevent the browser from performing the default action.

const handleSubmit = (e) => {
    e.preventDefault();
    console.log("The submit button was clicked!");
};

Handling Events in Class Components

Class components handle events similarly to functional components, with a few minor differences. Let's create a button which calls the handleClick function when clicked:

class App extends React.Component {
    handleClick = () => {
        console.log("This function has been triggered!");
    };
    render() {
        return (
            <div className="App">
                <h1>Hello World</h1>
                <button onClick={this.handleClick}>Trigger Function</button>
            </div>
        );
    }
}
Free eBook: Git Essentials

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

Note: We have to use this keyword because we are in the App class, and the handleClick is one of the member functions of that class.

Passing Parameters Into Events

It is best practice to declare the handler function as a method within the class component. If you want to pass parameters, props, or states to the rendered component later, you must bind the event handling function to this inside the constructor.

Let's say we have a state value set that we want to change when a specific button is clicked and we want to use the passed parameter, we'd have something like this, but it would throw an error:

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            title: "Welcome, We are glad you are here!"
        };
    }

    handleClick = (name) => {
        console.log("This function has been triggered!", name);
        this.setState({
            title: `Hello ${name}!`
        });
    };
    render() {
        return (
            <div className="App">
                <h1>{this.state.title}</h1>
                <button onClick={this.handleClick("Joel")}>
                    Trigger Function
                </button>
            </div>
        );
    }
}

To solve the issue, we either use arrow functions or Function.prototype.bind] to bind the this keyword:

<button onClick={() => this.handleClick("John Doe")}>Trigger Function</button>
<button onClick={this.handleClick.bind(this, "John Doe")}>Trigger Function</button>

Handling onSubmit Event

We can also handle all types of events with class components, as long as we use the this keyword instead of function when declaring the methods:

class App extends React.Component {
    handleSubmit = (e) => {
        e.preventDefault();
        console.log("The submit button was clicked!");
    };
    render() {
        return (
            <div className="App">
                <h1>Hello World</h1>
                <form onSubmit={this.handleSubmit}>
                    <label>Name</label>
                    <input type="text" />
                    <button type="submit">Submit</button>
                </form>
            </div>
        );
    }
}

Conclusion

We've seen in this guide that React events are very similar to JavaScript events, with a few differences in syntax and propagation behavior. We also learned the distinction between event handlers used in functional and class components, with the class component requiring the binding of the handlers to this. There are many more events that can be handled in React, but they all function in the same way as the onClick method, whether in a functional or a class component.

Last Updated: June 15th, 2022
Was this article helpful?

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

Joel OlawanleAuthor

Frontend Developer & Technical Writer

© 2013-2024 Stack Abuse. All rights reserved.

AboutDisclosurePrivacyTerms