React - Event Handling
When building React applications, one of the most important things you’ll do is make your app respond to user interactions. Whether it’s clicking a button, typing into an input field, submitting a form, or hovering over an element — your app should be able to “listen” for these events and respond appropriately.
This process of making your React app interactive is called **responding to events**.
Let us learn how they work in React, and how to handle them properly using event handlers and functions.
1. What Are Events?
An event* is any action that occurs as a result of user interaction with the browser. Common examples of events include:
* A user clicking a button
* A user typing in an input field
* A form being submitted
* The mouse hovering over an element
* A key being pressed* on the keyboard
In plain HTML and JavaScript, you might have handled events using attributes like “onclick”, “onchange”, or “onmouseover”. For example:
<button onclick=”alert(‘Button clicked!’)”>Click Me</button>
In React, we handle events in a similar way — but with a few key differences in syntax and approach.
2. Handling Events in React
In React, events are handled using event handler functions. These are functions that you define and attach to elements to tell React what to do when a certain event happens.
Here’s a simple example:
Let’s break this down:
- We created a function called handleClick(). This function defines what should happen when the button is clicked — in this case, it displays an alert message.
- We attached this function to the button using the onClick attribute.
- When the user clicks the button, React automatically calls the handleClick() function.
3. The Differences Between HTML and React Events
Even though React’s event handling looks similar to plain HTML, there are some important differences:
1. Event names are written in camelCase
In HTML, you’d write onclick.
In React, you must write onClick.
Similarly:
onchange → onChange
onmouseover → onMouseOver
onsubmit → onSubmit
2. You pass a function, not a string
In HTML, you might write this:
<button onclick=”alert(‘Clicked!’)”>Click Me</button>
But in React, you must pass a function reference, not a string:
<button onClick={handleClick}>Click Me</button>
If you include parentheses (handleClick()), it will run immediately when the component renders — which is not what we want. You just pass the function name (handleClick) without parentheses so that React can call it later when the event happens.
4. Handling Events with Parameters
Sometimes, you may need to pass additional data to your event handler. For example, you might want to display the name of the button clicked.
Here’s how you can do that:
In this example:
- We’re using an arrow function inside the onClick event.
- The arrow function calls handleClick(“LWB”) when the button is clicked.
- The alert displays “Hello, LWB!” when the user clicks the button.
If you directly wrote onClick={handleClick(“LWB”)}, it would call the function immediately instead of waiting for a click. It won’t fire on click—it fires every time the component renders. That’s why we wrap it in another function — so that it’s only called when the click actually happens.
7. Common React Events
React supports many types of events. Here are some of the most commonly used ones:
onClick – Fired when an element is clicked |
onChange – Fired when the value of an input changes |
onSubmit – Fired when a form is submitted |
onMouseOver – Fired when the mouse hovers over an element |
onKeyDown – Fired when a key is pressed down |
onFocus – Fired when an element (like input) gains focus |
onBlur – Fired when an element loses focus |
8. Different Ways to Handle Events in React
There are four common approaches to writing event handlers in React:
1. Using an inline anonymous ES5 function
2. Using an inline anonymous ES6 (arrow) function
3. Using a separate function declaration
4. Using a separate function expression
Let us recognize and choose between these approaches when working on your React projects.
To keep things simple, each function in our examples will just log a short message to the console. This will allow you to easily compare their syntax, while the outcome — logging text to the console — remains the same across all examples.
a. Handling Events with Inline Anonymous ES5 Functions
In this first approach, you directly pass an anonymous ES5 function as the value of the onClick attribute. Here’s what it looks like:
In this example:
* We define a function directly inside the `onClick` attribute.
* The function logs `’first example’` to the console when the button is clicked.
While this syntax is perfectly valid, it’s not commonly used in modern React applications. The ES5 `function` keyword tends to make code look bulkier, and most developers now prefer more concise syntax using arrow functions.
b . Handling Events with Inline Anonymous ES6 (Arrow) Functions
A more modern and cleaner approach is to use an inline ES6 arrow function for event handling. Here’s the same example rewritten using arrow function syntax:
This version is functionally identical to the previous one, but the syntax is shorter and easier to read.
This approach is quite common in React, especially for simple interactions that can be handled with one line of code.
If you prefer to keep your event logic inside the JSX — without needing a separate function elsewhere — this method is a great choice.
However, be cautious when using inline arrow functions for complex logic or frequently re-rendering components, as they can create new function instances on every render. While usually not a big issue, it can impact performance in large applications.
c. Handling Events with Separate Function Declarations
Sometimes, your event-handling logic might be too complex to fit neatly inside an inline function. In those cases, it’s better to define your function separately and then reference it in the event handler.
Here’s how that looks:
In this example:
* The `thirdExample` function is defined separately inside the `App` component.
* The button’s `onClick` attribute simply references that function.
When you click the button, React calls the `thirdExample()` function, which logs `’third example’` to the console.
This approach is ideal when:
* The event logic involves multiple steps or several lines of code.
* You want to reuse the same function for multiple buttons or elements.
* You prefer clearer and more maintainable code.
Even though the example only logs a short message, imagine replacing it with a 20-line function that performs complex calculations, API calls, or state updates — a separate function makes that much easier to manage.
d. Handling Events with Separate Function Expressions
Now let’s look at function expressions, which are slightly different from function declarations.
You can tell whether a function is a *declaration* or an *expression* by looking at how it starts.
If it begins with the keyword `function`, it’s a declaration.
If it’s assigned to a variable (like `const`, `let`, or `var`), it’s an expression.
Here’s how you can define a function expression using an ES6 arrow function:
In this example:
* We define an arrow function and assign it to a constant variable named `fourthExample`.
* The button’s `onClick` attribute references that constant.
When the button is clicked, `’fourth example’` is logged to the console.
This approach is very common in React because:
* It uses modern ES6 syntax.
* It allows you to define concise, readable functions.
* You can easily expand it to handle more complex logic or use React hooks inside.
For example, you can later modify `fourthExample` to perform multiple tasks, update component state, or make API calls — all while keeping your event handler clean and organized.
Lets understand and summarize all these different methods
|Inline anonymous ES5 function – onClick={function() { … }} – Rarely used in modern React
Inline anonymous ES6 (arrow) function – onClick={() => …} – Common for simple, short logic
Separate function declaration – function handleClick() { … } – Best for complex or reusable logic
Separate function expression – const handleClick = () => { … } – Very common and flexible approach