Event Handling in React: A Beginner’s Guide

In React, event handling is similar to JavaScript, but the key difference is that in React, JSX syntax is used, and event handlers are written in camelCase.

In this post, you’ll learn about how events work in React, the use of inline and separate event handlers, event objects, synthetic events, and best practices for handling events efficiently.

Before we get started, don’t forget to subscribe to my newsletter!
Get the latest tips, tools, and resources to level up your web development skills delivered straight to your inbox. Subscribe here!

Now let’s jump right into it!🚀

How Does Event Handling Work in React?

React events are based on the DOM but wrapped in synthetic events for better performance and cross-browser compatibility.

For example:

function ButtonClick() {
  function handleClick() {
    alert("Button Clicked!");
  }

  return <button onClick={handleClick}>Click Me</button>;
}

export default ButtonClick;

Here, onClick={handleClick} attaches the handleClick function to the button’s click event.

What are Synthetic Events?

Synthetic events are a wrapper around native browser events, which provides a consistent API across different browsers. React uses them to improve performance and ensure cross-browser compatibility.


React Events vs Traditional DOM Events

There are 3 major differences between React events and traditional DOM events:

FeatureVanilla JavaScriptReact
Event Syntaxonclick=”function()”onClick={function}
Function TypeCan be a string or functionMust be a function reference
this HandlingDefaults to windowBound to the component

Inline Event Handling

You can define event handlers inline like this:

return (
  <button onClick={() => alert("Clicked!")}>Click Me</button>
);

However, using inline functions inside JSX can affect performance if overused, especially in re-rendering scenarios.


Best Practice for Event Handlers

If you want to keep your code clean and reusable, then it’s a best practice to define the event handler in a separate function instead of inline.

For example:

function Greeting() {
  function sayHello() {
    alert("Hello, React!");
  }

  return <button onClick={sayHello}>Say Hello</button>;
}

Here, the sayHello function is a separate function that will handle the event.

This makes your code cleaner and easier to reuse.


Understanding the Event Object

Every event in React comes with an event object that contains useful details about the event.

For example:

function InputLogger() {
  function handleChange(event) {
    console.log("Input Value:", event.target.value);
  }

  return <input type="text" onChange={handleChange} />;
}

Here, event.target.value logs the input value in the console whenever the user types.


Why Synthetic Events?

React uses synthetic events as a wrapper around native browser events, providing:

  • Cross-browser compatibility
  • Optimized performance
  • Automatic event pooling

For example:

function FormHandler() {
  function handleSubmit(event) {
    event.preventDefault(); // Prevent page reload
    alert("Form Submitted!");
  }

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

Here, the default behavior (reload) of the form is prevented using the event.preventDefault().


Event Binding & Arrow Functions in Class Components

When you use class components, then event binding is required to preserve this context.

Example: Event Binding in a Class Component

class Counter extends React.Component {
  constructor() {
    super();
    this.state = { count: 0 };
    this.increment = this.increment.bind(this);
  }

  increment() {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return (
      <button onClick={this.increment}>
        Count: {this.state.count}
      </button>
    );
  }
}

Here, writing this.increment = this.increment.bind(this); is necessary otherwise this will be undefined inside increment( ).

Solution: Using Arrow Functions

class Counter extends React.Component {
  state = { count: 0 };

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return <button onClick={this.increment}>Count: {this.state.count}</button>;
  }
}

Arrow functions automatically bind this, eliminating the need for manual binding.


Handling Multiple Events in a Component

If you need to handle multiple events inside a component, then you can define event handlers separately.

For example:

function MultiEventHandler() {
  function handleFocus() {
    console.log("Input focused");
  }

  function handleBlur() {
    console.log("Input blurred");
  }

  return <input onFocus={handleFocus} onBlur={handleBlur} />;
}

Here,

  • onFocus gets triggered when the input is focused.
  • onBlur gets triggered when the focus moves out of input.

Passing Arguments to Event Handlers

If you want to pass arguments in event handlers, then you can use the arrow functions.

For example:

function ShowMessage() {
  function handleClick(message) {
    alert(message);
  }

  return <button onClick={() => handleClick("Hello!")}>Click Me</button>;
}

You can also pass the event object along with arguments:

return (
  <button onClick={(event) => handleClick("Hello!", event)}>Click Me</button>
);

Event Handling in Controlled vs Uncontrolled Components

In React, event handling is very important when you are working with forms and inputs.

  • Controlled Components: The data of the input is managed with React state.
  • Uncontrolled Components: The data is managed directly with the DOM.

Example: Controlled Input

function ControlledInput() {
  const [text, setText] = useState("");

  function handleChange(event) {
    setText(event.target.value);
  }

  return <input type="text" value={text} onChange={handleChange} />;
}

Here, value={text} is controlling the input with React state.

Example: Uncontrolled Input

import { useRef } from "react";

function UncontrolledInput() {
  const inputRef = useRef(null);

  function handleSubmit(event) {
    event.preventDefault();
    alert(`Input Value: ${inputRef.current.value}`);
  }

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

export default UncontrolledInput;

Here,

  • The ref (inputRef) is attached to the input field.
  • When the form is submitted, inputRef.current.value retrieves the input value directly from the DOM.
  • React does not control the input’s state.

This is useful when you don’t need to update the input value frequently or want to integrate with non-React code.


Commonly Used Events in React

Here are the most commonly used events in React:

EventDescription
onClickTriggered on the click of button or any other element.
onChangeTriggered when the value changes in an input field.
onSubmitTriggered when a form is submitted.
onMouseOverTriggered when the mouse hovers over an element.
onKeyPressTriggered when a key is pressed.
onFocusTriggered when an input field gains focus.
onBlurTriggered when an input field loses focus.

🎯Wrapping Up

That’s all for today!

I hope this post helps you.

If you found this post helpful, here’s how you can support my work:
Buy me a coffee – Every little contribution keeps me motivated!
📩 Subscribe to my newsletter – Get the latest tech tips, tools & resources.
𝕏 Follow me on X (Twitter) – I share daily web development tips & insights.

Keep coding & happy learning!

Leave a Comment