In this article, we will be looking at how to handle events in React. Specifically, we’ll look at how to listen for some of the most common event types. We’ll also look at some of the event properties which you can work with in order to listen for two or more events at the same time. Lastly, we’re going to look at some of the event handling ‘gotchas’ in React.

How to Listen to Events

Not unlike libraries such as jQuery, React has its own event handling system which is called Synthetic Events. Synthetic Events is a cross-browser wrapper of the browser’s native event. It works the same way as the event system that you find on browsers, the only difference is that the same code will work across all browsers.

Click

Here’s an example of how to listen for a click event:

import React, { Component } from 'react'; class ShowAlert extends Component { showAlert() { alert("Im an alert"); } render() { return ( show alert ); } } export default ShowAlert;

The onClick attribute is added to the target element in order to specify the function to be executed when that element is clicked. Note that this isn’t limited to just buttons, you can add the onClick attribute on any element or custom component that you create. In the example above, the showAlert() function is executed once the button is clicked. onClick is a type of mouse event.

Change

Now let’s take a look at the onChange event. This is commonly used for text fields to listen for when the user types something in it. Here’s an example of how to update the contents of an element based on the current value of a text field:

import React, { Component } from 'react'; class ChangeInput extends Component { constructor(props) { super(props); this.state = { name: '' }; } changeText(event) { this.setState({ name: event.target.value }); } render() { return (

What’s your name: { this.state.name }

); } } export default ChangeInput;

Here we’re adding the onChange attribute to the element which we want to listen for changes in contents. Note that unlike the onClick attribute, you can’t just add this to any element. You can only add it to the input of type text , textarea and select . The current value of the target element is stored in the target.value property of the event object. The event object gets passed as an argument to the function that you passed in to the onChange attribute. In order to update the contents of the h3 element, we update the component’s state with the current value of the text field.

You can find out more about handling events in forms by reading the documentation on Forms in React.

Hover

Next is the hover event. In the example below, the box will change its background color depending on whether its currently being hovered over or not. Just like the previous example, this uses state to update the styles of the box. But instead of one attribute, you need to add two: onMouseEnter and onMouseLeave . Both are pretty self-explanatory, all you have to do is assign the function that changes the default color to the onMouseEnter attribute. And then the function for bringing back the default color to the onMouseLeave attribute.

See the Pen AppendTo: React Events 101 – Hover by Wern Ancheta (@wernancheta) on CodePen.

Here are the codes:

import React, { Component } from 'react'; var styles = { box: { width: '100px', height: '100px' }, in: { backgroundColor: 'red' }, out: { backgroundColor: 'green' } }; class HoverBox extends Component { constructor(props) { super(props); this.state = { box_state: 'out' }; } changeColor() { this.setState({ box_state: 'in' }); } resetColor() { this.setState({ box_state: 'out' }); } render() { return (

); } } export default HoverBox;

Event Properties

We already know that an event object gets passed to the function that takes care of handling the event. As we’ve seen earlier, there’s the target property which allows us to get the actual element being targetted by the event. If its a text field, the current value can be found on the value property of the target .

Depending on the type of event, there are different properties that you can access in order to further customize how events will be handled. For example, the onClick event is a type of Mouse Event. But we can also use it in combination with other events. One common example of this is the pressing of the Ctrl key on the keyboard while clicking on the files you want to select.

Here’s a React component that simulates that behavior:

See the Pen AppendTo: React Events 101 – Select Boxes by Wern Ancheta (@wernancheta) on CodePen.

Here are the codes:

import React, { Component } from 'react'; var styles = { box_container: { padding: '20px' }, box: { width: '50px', height: '50px', float: 'left', marginLeft: '10px' }, default_box: { backgroundColor: 'gray', }, selected_box: { backgroundColor: 'orange' } } class SelectBoxes extends Component { constructor(props) { super(props); this.state = { boxes: [ false, false, false ] } } selectBox(index, event) { var box_states = this.state.boxes; if(!event.ctrlKey){ box_states = [ false, false, false ]; } var is_selected = box_states[index]; box_states[index] = !is_selected; this.setState({ boxes: box_states }); } renderBoxes() { return this.state.boxes.map((is_selected, index) => { let box_type = 'default_box'; if(is_selected){ box_type = 'selected_box'; } return (

); }); } render() { return ( { this.renderBoxes.call(this) } ); } } export default SelectBoxes;

In the constructor, we’ve initialized the state with an array containing the select state for each of the boxes. These boxes represent the files. The renderBoxes() method renders the boxes and styles them according to their select state. If a box is clicked without simultaneously pressing the Ctrl key, it resets the state to its default one (everything is deselected) because ctrlKey property would have false as its value. Below that, we simply toggle the select state of the box being clicked on.

Another example is keyboard events such as onKeyUp , onKeyDown and onKeyPress . When used, each of these events have properties pertaining to the actual key that you pressed:

altKey – a boolean value indicating whether the alt key is pressed along with another key.

– a boolean value indicating whether the alt key is pressed along with another key. charCode – the code of the key being pressed.

– the code of the key being pressed. ctrlKey – a boolean value indicating whether the Ctrl key is pressed along with another key.

– a boolean value indicating whether the Ctrl key is pressed along with another key. key – the actual key that was pressed.

– the actual key that was pressed. shiftKey – a boolean value indicating whether the shift key is pressed along with another key.

– a boolean value indicating whether the shift key is pressed along with another key. which – pretty much the same as the charCode .

There are many other properties which you can use based on the event type, so be sure to check out the list of supported events in React.

React Event Handling Gotchas

Lastly, let’s take a look at some of the most common gotchas when it comes to event handling:

this can have different meaning.

can have different meaning. You can’t listen to events directly from your custom components.

Not all DOM events have SyntheticEvent equivalents.

this can have different meaning

this can have a different meaning depending on how you attached the event handling function. For example, in the ShowAlert component earlier. We just specified the function directly without binding it to the component context:

show alert

This is because we didn’t really need to access anything in the component context (e.g. the state). But if you need to be able to access the state and manipulate it, you have to use bind to bind the component context to the function. This way you can use this inside the function to refer to the component itself:

Note that this is only true if you’re using ES6 classes to declare your components. If you’re using React.createClass , this will always refer to the component without the need to use bind .

You can’t listen to events directly from your custom components

If you have a custom component named Box , you can’t do something like this:

import Box from './components/Box'; class App extends Component { danceBox() { //make the box dance } render() { return } }

See what we did there? We added the onClick event handler directly to the Box component. But this wouldn’t really work because this only means we’re passing in an onClick props to the Box component. To actually attach the click event handler, you need to add onClick to the actual component. It’s not really a good practice to use reserved words for props so you need to change the name as well:

Then on the Box component, use the clickHandler props:

click me

Not all DOM events have SyntheticEvent equivalents

If you compare the DOM events listed on MDN with the Synthetic events in React, you’ll see that not all of the DOM events has an equivalent synthetic event. For example, there’s no synthetic event for listening for when the browser window is resized. In such cases, we need to fallback to DOM events to do the work for us. All you have to do is to attach the event listener using window.addEventListener . This accepts the event you want to listen to as its first argument, and the function that will handle the event as the second argument. The attaching of the event listener is done when the component has been mounted ( componentDidMount ). Don’t forget to remove it when the component is unmounted ( componentWillUnmount ). The handleResizedScreen function handles the event by getting the current width and height of the window, then updating the state so that the displayed width and height also changes.

import React, { Component } from 'react'; import '../App.css'; class ResizeWindow extends Component { constructor(props) { super(props); this.state = { width: window.innerWidth, height: window.innerHeight }; } handleResizedScreen() { this.setState({ width: window.innerWidth, height: window.innerHeight }); } componentDidMount() { window.addEventListener("resize", this.handleResizedScreen.bind(this)); } componentWillUnmount() { window.removeEventListener("resize", this.handleResizedScreen.bind(this)); } render() { return (

{ this.state.width } x { this.state.height }

); } } export default ResizeWindow;

Here are the contents of the App.css file:

.centered { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 30px; }

Conclusion

That’s it! In this tutorial you’ve learned all about events in React. With this knowledge, you’ll now be able to create React apps that makes full use of events. You can find all the codes used in this tutorial in this Github repo. For more information regarding events in React, check out the official documentation on Events.