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, that 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 stopPropagation() and 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 in React can be as simple as the example below.
In the example above, theonClick 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 turns shows the alert box.
Binding in render()
One way of resolving the problem of binding is to call bind in render function.
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 render()function.
Although, 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 might get 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 constructor.
this.changeText = this.changeText.bind()
Let’s go over how the line of code above works.
The first this.changeText refers to the changeText method. Since this is done in the constructor, ‘this’ refers to the ChangeInput class component.
The second this.changeText is also referring to the same changeText()method but we are now calling .bind() on it.
The final ‘this’ is the context in which we are passing to .bind() and it is referring 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.setState because this will be undefined. This is another important reason to bind event handling functions.
Binding with arrow function
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 this, arguments, super, or new.target.
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 a very simple and easy to read one.
This methods also has it’s performance costs just like binding in the render function method.
When it comes to events in React, only DOM elements are allowed to have event handlers. Take an 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 pass 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 button.
Event handlers are what is used in determining what action is to be taken when an event occurs. The onClick event is used to list 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?
On most apps, the performance implications of the binding the in the render function won’t be noticeable, therefore you can consider using the method for readability and maintenance advantages.
But for superior performance, you can consider using the binding in the constructor method.
Plug: LogRocket, a DVR for web apps
LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.