Course: Section

Get Started with Modern React: Step by Step

Episode: Title

S02・V11: Handling Events

Date Created: July 17th, 2019
Last Updated: 27 days ago

Objectives
  1. We will show the difference between handling DOM events in HTML, and handling events with React elements.
  2. We will show how to prevent default browser behavior in React.
  3. We will provide an example to show you how to create an event handler in React, and how to specify an extra parameter for it.
Watch Video
Duration: 7m 25s

Handling Events

Handling events with React elements is very similar to handling events on DOM elements in HTML. However, there are some syntactic differences. Firstly, React events are named using camel-case, rather than lower-case. Secondly, with JSX you pass a function as the event handler, rather than a string.

Button

An example of a button expressed in HTML is:

// HTML Syntax
<button onclick="activateLasers()">Activate Lasers</button>
// `onclick` is lower-case, passed function is `"activateLasers()"`

Note that the onclick attribute is spelled using lower-case, and the value passed to it is a function call as a string: "activateLasers()".

Now, the same button expressed in React JSX syntax would be:

// React JSX Syntax
<button onClick={activateLasers}>Activate Lasers</button>
// `onClick` is camel-case, passed function is `{activateLasers}`

Note that the onClick prop is spelled using camel-case, and the value passed to it is a reference to a function, within a JSX container: {activateLasers}.

Please take a note of the differences between HTML and JSX syntax conventions.

Default Browser Behavior

Now, when clicking a link, the default browser behavior is to open a new page.

To prevent this default behavior in HTML, we can return false; within the string passed to the onclick attribute.

// HTML Syntax
<a href="" onclick="console.log('Link clicked'); return false">Click me</a>

In React, we would need to call preventDefault() on the event to avoid a new page from loading.

// React JSX Syntax 
<a href="" onClick={event => {
  event.preventDefault();
  console.log('Link clicked');
}}>
  Click me
</a>

Here, event is a “synthetic event” created by React. React defines these synthetic events according to the W3C spec, so you don’t need to worry about cross-browser compatibility. When using React you should generally not need to call addEventListener to add listeners to a DOM element after it is created. Instead, just provide a listener when the element is initially rendered.

Event Handler

A common pattern is for an event handler to be a function within your component.

For example, let’s say we have a Toggle component which renders a button that lets the user toggle between “ON” and “OFF” states. Inside Toggle, we will first add the isToggleOn state to true initially. We will now name the state value getter and state setter function in the returned two-element array. Now, we will have the component return a button showing the text “ON” or “OFF” depending on the isToggleOn state.

import React, { useState } from "react";
import ReactDOM from "react-dom";

const Toggle = () => {
  const [isToggleOn, setToggleOn] = useState(true);

  return (
    <button>
      {isToggleOn ? "ON" : "OFF"}
    </button>
  );
};

ReactDOM.render(<Toggle />, document.getElementById("root"));

The button will need to have an onClick prop to listen for click events. Let’s pass a reference to an event handler function which we will define inside the component, which is a common pattern in React. Within the handleClick function, we will toggle the state using setToggleOn(!isToggleOn).

import React, { useState } from "react";
import ReactDOM from "react-dom";

const Toggle = () => {
  const [isToggleOn, setToggleOn] = useState(true);

  const handleClick = event => {    setToggleOn(!isToggleOn);  };
  return (
    <button onClick={handleClick}>      {isToggleOn ? "ON" : "OFF"}
    </button>
  );
};

ReactDOM.render(<Toggle />, document.getElementById("root"));

Toggle the button in the browser to test it.

Equivalently, we can write the expression passed to the onClick prop as follows:

import React, { useState } from "react";
import ReactDOM from "react-dom";

const Toggle = () => {
  const [isToggleOn, setToggleOn] = useState(true);

  const handleClick = event => {
    setToggleOn(!isToggleOn);
  };

  return (
    <button onClick={event => handleClick(event)}>      {isToggleOn ? "ON" : "OFF"}
    </button>
  );
};

ReactDOM.render(<Toggle />, document.getElementById("root"));

Passing Arguments to Event Handlers

Inside a loop, where we render several items, such as the rows of a table, we commonly want to pass an extra parameter to an event handler, to be able to identify each item.

For example, let’s say our app renders 5 Toggles. We will map over an array with 5 elements to achieve this.

const App = () => (  <div>    {[1, 2, 3, 4, 5].map(row => (      <div key={row}>        <Toggle />      </div>    ))}  </div>);
ReactDOM.render(<App />, document.getElementById("root"));

We will pass the row number to the Toggle as a prop. We can now make use of the row number in the Toggle component, via props. We can pass the row number as the first argument to the event click handler. We will need to update the function signature of our handleClick function, with the row as the first parameter. Now, we can print out which row was clicked.

import React, { useState } from "react";
import ReactDOM from "react-dom";

const Toggle = props => {
  const [isToggleOn, setToggleOn] = useState(true);

  const handleClick = (row, event) => {    console.log(`Row #${row} was clicked`);    setToggleOn(!isToggleOn);
  };

  return (
    <button onClick={event => handleClick(props.row, event)}>      {isToggleOn ? "ON" : "OFF"}
    </button>
  );
};

const App = () => (
  <div>
    {[1, 2, 3, 4, 5].map(row => (
      <div key={row}>
        <Toggle row={row} />      </div>
    ))}
  </div>
);

ReactDOM.render(<App />, document.getElementById("root"));

Save the file, and test the app in the browser, using the JavaScript Console.

Summary

We showed the difference between handling DOM events in HTML, and handling events with React elements. We showed how to prevent default browser behavior in React. And, we provided an example to show you how to create an event handler in React, and how to specify an extra parameter for it.

Next Up…

In the next video, we will render elements based on certain conditions.