Navigate back to the homepage
Try NowLogin

React’s onClick Event Handler Explained

Felix Gerschau
December 23rd, 2020 · 3 min read


  • The onClick handler allows you to pass a function to a component, which will be executed when it’s clicked.
  • Call e.preventDefault() to prevent native default behavior, like submitting a form.
1const App = () => {
2 const sendMessage = (e) => {
3 e.preventDefault();
4 alert('hi');
5 }
7 return (
8 <button onClick={sendMessage}>
9 Send message
10 </button>
11 )

Handling onClick events in functional components

Event handlers are functions that get executed when a given event happens. For example, you can use them to send a message after the user clicks on a button.

You might already know event handlers from plain HTML and JavaScript. Event handlers in React are very similar.

HTML provides us with event handlers like onclick, onchange, onfocus, and many more. We can use them by adding them to the HTML element as an attribute.

1<button onclick=”sendMessage();”>
2 Send

We can do the same in React as well. Most of the time, React’s event handlers have the same name as in HTML, but they are written in camelCase. The handlers above would translate to onClick, onChange, and onFocus in React.

1<button onClick={sendMessage}>
2 Send

As you can see, it’s not exactly like in the HTML example. First, curly braces ({}) replace the double quotes () used in HTML.

Curly braces are using in JSX syntax to separate the markup from JavaScript.

Everything that’s inside the braces is evaluated as JavaScript. Everything outside of them is the markup that will be rendered.

For a more complete picture, let’s see how the complete component may look like.

1const App = () => {
2 const sendMessage = () => {
3 alert('hi');
4 }
6 return (
7 <button onClick={sendMessage}>
8 Send message
9 </button>
10 );

Play around with the code of this example on codepen.

Here we see why we needed to put sendMessage in curly braces. We define the sendMessage function as a variable at the beginning of the component.

A common mistake here is to call the function right away (like in the HTML example).

1<button onClick={sendMessage()}>

Instead of calling the function when the button is clicked, it will be called every time the component renders.

We only need to pass down the function itself without calling it.

1<button onClick={sendMessage}>

Alternatively, you can also inline the function itself.

1<button onClick={() => sendMessage()}>

Note how we call sendMessage in the inlined function. We do this because it’s part of the inlined function, which we don’t call right away.

React’s synthetic events

As you may have already heard, React has a virtual DOM, which is an abstraction layer that React uses to optimize renders and some browser-specific features.

This means that even though the code we write in React looks similar to HTML, it’s not quite the same.

I wrote an article on how this works exactly. You can check it out here.

Just like React adds an abstraction on top of the DOM, it also adds an abstraction layer to events. React’s events are called synthetic events.

Synthetic events are a wrapper around events that improve performance and normalize the events so that they look the same across all browsers.

Such events are passed to the event handlers, like onClick. We can use it to access the value attribute of the button element.

1const App = () => {
2 const sendMessage = (e) => {
3 console.log('value',; // output: “value somevalue”
4 alert('hi');
5 }
7 return (
8 <button value="somevalue" onClick={sendMessage}>
9 Send message
10 </button>
11 )

React preventDefault()

Accessing the value attribute is usually done when dealing with text inputs and not in combination with onClick.

What you’ll rather encounter in React applications is the following:

1const sendMessage = (e) => {
2 e.preventDefault();
3 alert('hi');

We call the preventDefault function in the event handler, which the synthetic event provides. The name already gives away what it does: It prevents the event from executing the default behavior.

To understand this a little better, we need to know the default behavior of different HTML elements.

If the button element is located inside a form element, the default behavior is to submit the form.

This was fine when HTML forms only had one button anyway, but what if you only want to run the code of the onClick function without submitting the form?

In React, we usually solve this by putting e.preventDefault() at the beginning of the event handler.

Alternatively, you could also solve this natively by changing the type attribute of the button:

1<button type=”button”>Click me!</button>

Form elements have an even worse default behavior: They refresh the entire page after the onSubmit event—not something you want to happen in a Single Page Application.

Handling onClick events in class components

In the previous section, I only focused on functional components. While this is the easiest way of writing components in React, you’ll still encounter components written as JavaScript classes from time to time.

So let’s have a look at the previous example as a React class:

1class App extends React.Component {
2 sendMessage = (e) => {
3 e.preventDefault();
4 console.log('value',; // output: “value somevalue”
5 alert('hi');
6 };
8 render() {
9 return (
10 <button value="somevalue" onClick={this.sendMessage}>
11 Send message
12 </button>
13 );
14 }

As you can see, the way we handle onClick events in React classes is the same as in functional components. The function sendMessage is now part of the App class, which is why we access it via this.

In case you were wondering why I defined sendMessage as a variable and not as a method of the class: This is to preserve the scope of the class inside the function, which practically means that I will be able to call this.setState inside the function.

Observability for Production React Apps

Debugging React apps in production may be challenging and time consuming. Asayer is a frontend monitoring tool that replays everything your users do and shows how your app behaves and renders for every issue. It’s like having your browser’s inspector open while looking over your user’s shoulder.

Asayer Frontend Monitoring

Asayer helps to quickly get to the root cause by reproducing issues as if they happened in your own browser. It also monitors your frontend performance by capturing key metrics such as page load time, memory consumption and slow network requests as well as Redux actions/state.

Happy debugging, for modern frontend teams - Start monitoring your web app for free.

More articles from Asayer Blog

JWT Authentication Best Practices

The importance of securing frontend client, micro-service communication and client-microservice interaction through JSON Web Tokens.

December 4th, 2020 · 12 min read

JavaScript Heap Out Of Memory Error

A quick solution that you can use to fix "Heap Out Of Memory Error" in JavaScript. We lay out the causes and how to prevent them.

November 30th, 2020 · 4 min read
© 2020 Asayer Blog
Link to $ to $ to $