Skip to main content
9

React Event Handlers Tutorial: Complete Guide to onClick and Event Handling

React Fundamentals 7 min read Updated June 19, 2025 Free

Learn how to handle user interactions in React by implementing event handlers for clicks, form submissions, and more.

Introduction

A button is meant to be clicked, and when it’s clicked we intrinsically expect something to happen? right?

Well, the thing that will happen is defined by you the developer as a Javascript function doing something, let’s say displaying an alert message as an example.

The function whose job is to respond to an event triggered by something like a user interaction such as clicking is called an event handler, and it’s a normal javascript function declared within the component. And can be attached to any JSX element such as buttons, divs, inputs and so on.

Usually, the React community follows the naming convention that consists of starting the event handler’s name with handle followed by the event name. Some examples of that include: handleClick, handleHover, handleFocus and so on.

React makes attaching an event handler to a JSX element really straightforward.

We just have to assign the event handler (aka our locally declared function) into a special type of props starting with on then followed by the name of the event such as onClick, onFocus, onHover and so on.

In this article, we will dive deeper into event handlers while exploring important concepts that every developer needs to master such as:

  • Passing event handlers between React components.

  • Event propagation and why understanding it is so important.

  • And finally, How to stop event propagation and other browser defaults behaviors when needed.

So if that sounds interesting let’s dive in.

Event Handlers Basics

Let’s say that we’ve got a component, rendering a button saying Click me. Let’s define an event handler named handleClick as a locally declared function within the component as we’ve discussed previously.

And then attach it to the onClick button prop.

Keep in mind that you need to just assign the function name without calling it like this.

function Button(){

function handleClick(){
  alert("Stop Clicking")

}
return (
    <button onClick={handleClick}>Click me</button> {/* ✅ */}
    {/* <button onClick={handleClick()} />Click me </button> ❌ */ }
)
}

Calling it will just make the function run at every render which is not obviously our goal here.

Whenever the button gets clicked by the user **the function which is attached to the onClick prop is going to get called. Consequently the alert message will get displayed.

What if our component is receiving a username prop, can we accesses it in the event handler and concatenate it with a “Hi” message as shown bellow?


function Button({username}){

function handleClick(){
  alert("Hi "+ username)

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

Yes, actually that’s one of the advantages of declaring an event handler within the component. Doing so allows the event handler to access its parent’s outer scope variables or functions such as props or any other stuff.

Passing Event Handlers as Props

Okay, now imagine that you want to use the Button component in multiple places.

Declaring the handleClick event inside the component itself, will just make it less reusable. So can we instead pass the event handler as a prop.

Yes, absolutely! As you may know functions are first class citizens in Javascript. Consequently, they can be passed to other function, therefore React components. So it’s obviously possible to do that.

Let’s make our Button component accept a new prop called onClick, assign it to the button’s onClick prop, then declare a handleClick event handler inside the parent component itself. And then pass it to the Button child component.



function Button({username,onClick}){

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

function App(){

const username = "Sid Ali"
function handleClick(){
  alert("Hi "+ username)

}

  return (
    <div>
    <Button onClick={handleClick} username={username} />
    </div>

  )
}

By convention event handler props are named exactly as the JSX elements built-in events props. So they start with on followed by either the event name or the interaction that need to be performed such as onClick, onUploadFile, onTryingToFindARandomName and so on.

Event Propagation and Bubbling

Now let’s move on into a very important and interesting concept that is known as event bubbling or propagation.

But before that let me ask you a simple question.

What will happen if you have clicked on the child component of two nested JSX elements both having the onClick event attached to them? Which component will show its corresponding alert message?

Let’s say that we have a Parent and Child components.

An onClick event listener displaying an alert, is attached to the Child component and the parent component.

function Parent(){
  return (
    <div onClick={()=>alert("Hello From Parent")}>
      <Child1 />
    </div>
  )
}

function Child(){
  return (
    <button onClick={()=>alert("Hello from Child")}>Click me</button>
  )
}
-> (1) Hello from Child
-> (2) Hello from Parent 

The answer as you may have guessed is both but in a special order.

The alert message corresponding to the Child component will get displayed first, then the Parent will follow after that.

We call what have just happened event propagation or bubbling we say that the click event has propagated from the child to the parent.

Stopping Event Propagation

If you happen to be bothered by such default behavior you can stop the propagation by doing as follows:


function Child(){
  return (
    <button onClick={(e)=>{
      e.stopPropagation()
      alert("Hello from Child")}
      }>Click me</button>
  )
}

Every event handler has access to an optional e argument which is shorthand standing for event that you can use to either read information about it or perform actions on the event that has just have occurred.

Among those actions is being able to call the stopPropagation method on the e object to prevent the event from bubbling to its parent.

Alternative to Propagation

When stopping the default browser’s propagation, you may want to call the parent’s event handler after running some code at the child level.

You can absolutely do that as an alternative to propagation in the React way. By just passing the parent’s event handler as a prop and then calling it after stopping the propagation and running some code.


function Parent(){
  function handleClick(){
    alert("Hello From Parent")
  }
  return (
    <div onClick={handleClick}>
      <Child1  onClick={handleClick}/>
    </div>
  )
}

function Child({onClick}){
  return (
    <button onClick={(e)=>{
      e.stopPropagation();

      alert("Hello from Child");
      onClick()


    }}>Click me</button>
  )
}
-> (1) Hello from Child
-> (2) Hello from Parent 

Preventing Default Browser Behavior

In addition to propagation, there is another annoying event that you will definitely want to prevent.

When you submit a form by default the browser refreshes the page, therefore killing your entire React application and probably causing some side effects like smashing your keyboard from anger when that happens.

function Form(){

  function handleSubmit(e){
    alert("Hello From Form")
  }

  return (
    <form onSubmit={handleSubmit}>
      <button>Submit</button>
    </form>
  )
}
Browser Refresh Meme

So similarly to what we did to stop the propagation. All you need to do here is to go to the form’s onSubmit attached event handler, make sure to receive the e or event argument, then call the preventDefault method on the e object to prevent the default browser refresh behavior.

function Form(){

  function handleSubmit(e){
    e.preventDefault(); // This line prevents the browser's default behavior ✅
    alert("Hello From Form")
  }

  return (
    <form onSubmit={handleSubmit}>
      <button>Submit</button>
    </form>
  )
}

Conclusion

Events are happening all the time in a highly interactive web application.

But when an event fires it’s usually handled by modifying some components in the React application tree.

In the next article we will finally explore a fundamental concept that makes React reacts and remembers what have happened now and in the past after some series of interactions or events.

Thank you for watching and happy coding 🧑‍💻.