Course: Section

Get Started with Modern React: Step by Step

Episode: Title

S02・V18: Forms (Part 3)

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

Objectives
  1. We will show you a file input element.
  2. We will show you how to deal with multiple inputs.
  3. We will demonstrate that controlled inputs with a “null” or “undefined” value are editable.
Watch Video
Duration: 6m 8s

File Input

First, we will talk about the input type="file" element. In HTML, a input type="file" lets the user choose one or more files from their device storage to be uploaded to a server or manipulated by JavaScript via the File API.

Let’s show an example of it in React. We will render the input type="file" directly to the DOM.

src/index.js
import React, { useState } from "react";
import ReactDOM from "react-dom";

ReactDOM.render(
  <input type="file" />,  document.getElementById("root")
);

In the browser, you can see the UI of the input type="file" element. Because its value is read-only, it is an uncontrolled component in React.

Handling Multiple Inputs

We will now turn to dealing with multiple controlled input elements.

To show an example of this, let’s create and render a Reservation component.

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

const Reservation = () => {};

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

Within this component, we will define two pieces of local state, with the useState hook. The first piece of state in the Reservation component is going to record whether the user isGoing, with a default value of true. The second piece of state will keep track of the numberOfGuests, with a default value of 2.

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

const Reservation = () => {
  const [isGoing, setIsGoing] = useState(true);  const [numberOfGuests, setNumberOfGuests] = useState(2);};

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

We will return a form from the Reservation component.

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

const Reservation = () => {
  const [isGoing, setIsGoing] = useState(true);
  const [numberOfGuests, setNumberOfGuests] = useState(2);

  return (    <form>    </form>  );};

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

The first form element will be a input type="checkbox". It will have a label of Is going:.

Now we will add the input type="checkbox". It will be a controlled component, whose checked attribute is set to the isGoing state. We can listen to the checked value of the input type="checkbox" element via the onChange event listener. The onChange event listener fires a callback function whenever the checkbox’s value changes, with the event as its input argument. We can access the event target’s checked value after it has changed, and use it to setIsGoing.

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

const Reservation = () => {
  const [isGoing, setIsGoing] = useState(true);
  const [numberOfGuests, setNumberOfGuests] = useState(2);

  return (
    <form>
      <label>        Is going:        <input          name="isGoing"          type="checkbox"          checked={isGoing}          onChange={event => setIsGoing(event.target.checked)}        />      </label>    </form>
  );
};

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

We will then add a line break: <br />.

Our second form element will be a input type="number". It will have a label of Number of guests:. Here, we will add the input type="number". It will also be a controlled component, whose value attribute is set to the numberOfGuests state. Similar to a input type="text", we can listen to the event target’s value on the onChange event listener, and use it to set the number of guests.

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

const Reservation = () => {
  const [isGoing, setIsGoing] = useState(true);
  const [numberOfGuests, setNumberOfGuests] = useState(2);

  return (
    <form>
      <label>
        Is going:
        <input
          name="isGoing"
          type="checkbox"
          checked={isGoing}
          onChange={event => setIsGoing(event.target.checked)}
        />
      </label>
      <br />      <label>        Number of guests:        <input          name="numberOfGuests"          type="number"          value={numberOfGuests}          onChange={event => setNumberOfGuests(event.target.value)}        />      </label>    </form>
  );
};

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

We now can see two independent and controlled input elements in the browser. First, click on the isGoing checkbox. Then, increase the number of guests to 4.

Controlled Input Value of ‘null’

Specifying the value prop on a controlled component prevents the user from changing the input unless you desire so. If you’ve specified a value but the input is still editable, you may have accidentally set value to undefined or null.

We will demonstrate this by rendering an input with a value of null to the DOM.

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

ReactDOM.render(
  <input value={null} />,  document.getElementById("root")
);

Even though this is a controlled component, we can still edit it, as its value is null.

Uncontrolled Components

It can sometimes be tedious to use controlled components, because you need to write an event handler for every way your data can change and pipe all of the input state through a React component. This can become particularly annoying when you are converting a pre-existing codebase to React, or integrating a React application with a non-React library. In these situations, you might want to check out uncontrolled components, an alternative technique for implementing input forms.

Formik

If you’re looking for a complete solution which includes validation, keeps track of the visited fields, and handles form submission, Formik is a popular choice.

Summary

We showed you a file input element. We showed you how to deal with multiple inputs. And, we demonstrated that controlled inputs with a null or undefined value are editable.

Next Up…

In the next video, we will discuss “lifting state up”.