Yomi Eluwande JavaScript developer. Wannabe designer and Chief Procrastinator at Selar.co and worklogs.co.

React onClick event handlers: A complete guide

5 min read 1622

React Onclick Event Handlers Guide

Editor’s note: This post was updated on 8 July 2022 to ensure everything is up to date with regard to React 18 and to add a section about type checking in React with Typescript.

In this tutorial, we’ll go over the basics of React’s onClick event handler, including event listening, dealing with custom events, and using TypeScript to type check event handlers.

What we’ll cover:

What are event handlers in React?

Event handlers determine what action is to be taken whenever an event is fired. This could be a button click or a change in a text input.

Essentially, event handlers are what make it possible for users to interact with your React app. Handling events with React elements is similar to handling events on DOM elements, with a few minor exceptions.

If you’re familiar with how events work in standard HTML and JavaScript, it should be easy for you to learn how to handle events in React.

What is the onClick handler in React?

The React onClick event handler enables you to call a function and trigger an action when a user clicks an element, such as a button, in your app.

Event names are written in camelCase, so the onclick event is written as onClick in a React app. In addition, React event handlers appear inside curly braces.

Take the following simple example written in HTML:

<button onclick="sayHello()">
  Say Hello
<button>

In a React app, this button onClick event would be written as follows:



<button onClick={sayHello}>
  Say Hello
<button>

Another key difference is that you must explicitly call preventDefault in React, whereas in HTML, you would simply return false to avoid default behavior.

The following example shows how to prevent a link from opening a new page by default:

<a href="#" onclick="console.log('The link was clicked.'); return false">
  Click me
</a>

You would write this as follows in React:

function ActionLink() {
  const handleClick = (e) => {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <button onClick={handleClick}>
      Click me
    </button>
  );
}

What are synthetic events in React?

React implements a synthetic events system that brings consistency and high performance to React apps and interfaces. It achieves consistency by normalizing events so that they have the same properties across different browsers and platforms.

A synthetic event is a cross-browser wrapper around the browser’s native event. It has the same interface as the browser’s native event, including stopPropagation() and preventDefault(), except the events work identically across all browsers.

It achieves high performance by automatically using event delegation. In actuality, React doesn’t attach event handlers to the nodes themselves. Instead, a single event listener is attached to the root of the document. When an event is fired, React maps it to the appropriate component element.

React event listeners

To listen to events in React, add the onClick attribute — which is the event handler — to the target element. This specifies the function to be executed when that element is clicked, as shown below:


More great articles from LogRocket:


import React from "react";

const ShowAlertComponent = () => {
  const showAlert = () => {
    alert("I'm an alert");
  }

  return <button onClick={showAlert}>Show alert</button>;
}
export default ShowAlertComponent;

In the example above, the onClick attribute is set to the showAlert function as the event target, which displays the alert message “I’m an alert” on click of the button.

Handling events in React components

There are several ways to handle events in functional React components. We’ll go over five of them here.

Call an inline function in an onClick event handler

Inline functions allow you to write code for event handling directly in JSX. See the example below:

import React from "react";

const App = () => {
  return (
    <button onClick={() => alert("Hello!")}>Say Hello</button>
  );
};

export default App;

This is commonly used to avoid the extra function declaration outside the JSX, although it can be less readable and harder to maintain if the content of the inline function is too much.

Update the state inside an onClick event handler

Let’s say your React application requires you to update the local state in an onClick event handler. Here’s how to do that:

import React, { useState } from "react";

const App = () => {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <button onClick={() => setCount(count - 1)}>Decrement</button>
    </div>
  );
};

export default App;

In the example above, the value of useState is modified by the Increment and Decrement buttons, which have the setCount, an updater function inside the onClick event handler.

Call multiple functions in an onClick event handler

The onClick event handler also allows you to call multiple functions.

import React, { useState } from "react";

const App = () => {
  const [count, setCount] = useState(0);
  const sayHello = () => {
    alert("Hello!");
  };

  return (
    <div>
      <p>{count}</p>
      <button
        onClick={() => {
          sayHello();
          setCount(count + 1);
        }}
      >
        Say Hello and Increment
      </button>
    </div>
  );
};

export default App;

In the code block above, clicking the button increments the local state and alerts a message. Both actions are executed by separate functions in the onClick event handler.

Pass a parameter to an onClick event handler

Another common use case for event handlers is passing a parameter to a function so it can be used later. For example:

import React from "react";

const App = () => {
  const sayHello = (name) => {
    alert(`Hello, ${name}!`);
  };

  return (
    <button
      onClick={() => {
        sayHello("Yomi");
      }}
    >
      Say Hello
    </button>
  );
};

export default App;

Here, the sayHello function accepts a name as a parameter, which is then used to customize the alert message. In this case, the function accepts the name “Yomi” so that on click, the button displays “Hello, Yomi!” as its message.

Use synthetic events directly inside an onClick event handler

You can also use synthetic events directly inside an onClick event handler. In the example below, the button’s value is gotten via e.target.value and then used to alert a message.

import React from "react";

const App = () => {
  return (
    <button value="Hello!" onClick={(e) => alert(e.target.value)}>
      Say Hello
    </button>
  );
};

export default App;

Custom components and events in React

When it comes to events in React, only DOM elements are allowed to have event handlers. Take the example of a component called CustomButton with an onClick event. This button wouldn’t respond to clicks because of the reason above.

So how do we handle event handling for custom components in React?

By rendering a DOM element inside the CustomButton component and passing the onClick prop into it. Our CustomButton is essentially a pass-through for the click event.

import React from "react";

const CustomButton = ({ onPress }) => {
  return (
    <button type="button" onClick={onPress}>
      Click on me
    </button>
  );
};

const App = () => {
  const handleEvent = () => {
    alert("I was clicked");
  };
  return <CustomButton onPress={handleEvent} />;
};

export default App;

In the example above, the CustomButton component is passed a prop of onPress, which then gets passed into the onClick of the button.

Type checking in React with TypeScript

Here’s an an example on how to add type checking for event handling in React. The ChangeEvent type is imported from React and used against the event that is passed from the input element.

import {useState, ChangeEvent} from "react";

const InputComponent = () => {
  const [email, setEmail] = useState<string>('');

  const onChange = (e: ChangeEvent<HTMLInputElement>): void => {
    setEmail(e.target.value);
  };

  return <input type="text" placeholder="Enter email address" onChange={onChange} value={email} />;
}
export default InputComponent;

Let’s look at a complete form and how to add type to the event handler for the input and also the form submission.

import { useState, ChangeEvent, FormEvent } from 'react';

export default function App() {
  const [email, setEmail] = useState<string>('');
  const [password, setPassword] = useState<string>('');

  const handleSubmit = (event: FormEvent) => {
    console.log('Form was submitted!');
  };

  const handleEmailChange = (event: ChangeEvent<HTMLInputElement>) => {
    setEmail(event.target.value);
  };

  const handlePasswordChange = (event: ChangeEvent<HTMLInputElement>) => {
    setPassword(event.target.value);
  };

  return (
    <div className="App">
      <form onSubmit={handleSubmit}>
        <input type="text" placeholder="Enter email address" onChange={handleEmailChange} value={email} />
        <input type="password" placeholder="Enter password" onChange={handlePasswordChange} value={password} />
        <button type="submit">Submit</button>
      </form>
    </div>
  );
}

React provides a FormEvent type you can use and that is passed to the handleSubmit function. To learn more about React event handlers, check out this exhaustive list of event handler types that React provides.

Conclusion

Event handlers determine what action should be taken when an event occurs. The onClick event is used to listen for click events on DOM elements.

We also reviewed some common use cases of the onClick event handler in functional components, such as updating the state, calling multiple functions, and using synthetic events.

We addressed how the onClick event handler works in custom components, and lastly we looked at how to add typings to event handlers.

Yomi Eluwande JavaScript developer. Wannabe designer and Chief Procrastinator at Selar.co and worklogs.co.

4 Replies to “React onClick event handlers: A complete guide”

  1. Thanks brother. This is simple and adequate. It cleared all queries in my head.

  2. The code is to be changed. It should have been:

    “`js
    this.changeText = this.changeText.bind(this)
    “`

Leave a Reply