Event handlers are used to determine what action is to be taken whenever an event is fired. This could be a mouse click or a change in a text input.
In React apps, events are written in the camelCase format, which means the
onclick event will be written as
onClick in a React app.
React implements a synthetic event system that brings consistency and high performance to React applications and interfaces. It achieves consistency by normalizing events so that they have the same properties across different browsers and platforms.
Synthetic events is a cross-browser wrapper around the browser’s native event. It has the same interface as the browser’s native event, including
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.
Listening to events
Listening to events in React can be as simple as the example below.
In the example above, the
onClick attribute is our event handler, and it is added to the target element in order to specify the function to be executed when that element is clicked. The
onClick attribute is set to the
showAlert function, which alerts a message.
In simpler terms, this means that whenever the button is clicked on, the
showAlert function is called, which, in turn, shows the alert box.
One way of resolving the problem of binding is to call bind in a
In the example above, we are using the
onChange event handler to listen for typing events on a text input. This is done by binding it in the
render() function. This method requires calling
.bind(this) in the
bind() from the
Function method. So now when we call
onChange() inside JSX,
this will point to our class instance. Easy-peasy.
However, using this method means that there might be some performance implications since the function is reallocated on every render. This performance cost might be not be visible at all in small React apps, but it could become noticeable in bigger React apps.
If binding in the render doesn’t work for you, you can bind in the constructor. See an example below:
As you can see above, the
changeText function is bound in the
this.changeText = this.changeText.bind()
Let’s go over how the line of code above works.
this.changeText refers to the
changeText method. Since this is done in the constructor,
this refers to the
ChangeInput class component.
this.changeText is also referring to the same
changeText() method, but we are now calling
.bind() on it.
this is the context we are passing to
.bind(), and it refers to the
ChangeInput class component.
It’s also important to note that if
changeText isn’t bound to the class instance, it won’t be able to access
this will be
undefined. This is another important reason to bind event handling functions.
Binding with arrow functions
Another way of handling events is by binding with the fat arrow function. With ES7 class properties, we can do bindings at the method definition, as seen in the example below:
By definition, an arrow function expression has a shorter syntax than a function expression and does not have its own
In the example above, once the component has been created, the
this.handleEvent will never change again. That, in turn, means
<button> won’t get re-rendered. This approach is very simple and easy to read.
This methods also has its performance costs, just like binding in the render function method.
Custom components and events
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 wouldn’t respond to clicks because of the reason above.
So how do we handle event handling for custom components?
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.
In the example above, the
CustomButton component is passed a prop of
onPress, which then gets passed into the
onClick of the
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.
When it comes to event handling, binding is a very important topic, and there are several ways to go about it. So the question now is which of the binding methods do you use?
For most apps, the performance implications of binding in the render function won’t be noticeable, so you can consider using this method for readability and maintenance advantages.
But for superior performance, you should consider using the binding in the
onClick events in production
Debugging React applications can be difficult, especially when there is complex state. If you’re interested in monitoring and tracking Redux state for all of your users in production, try LogRocket.
LogRocket is like a DVR for web apps, recording literally everything that happens on your site. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.
The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.
Modernize how you debug your React apps — start monitoring for free.