3.4 Forms, States, and User Input


Forms, States, and User Input

React, similarly to HTML, uses forms to allow users to interact with the web page. Through forms, React can collect and process data from users. The term forms include all input fields from text boxes, checkboxes, radio buttons, etc.
Adding a form is fairly simple– just like adding any other React element. As in HTML, we use the <form> element to provide a way for users to enter data and submit it to the server:
notion image
We define a function component called MyForm with two input fields for the user's name and email, and a submit button. const root = ReactDOM.createRoot(document.getElementById('root')); We use the ReactDOM.createRoot() method to create a root React element that asynchronously renders the MyForm component into the DOM (a representation of the HTML elements currently rendered in the browser). root.render(<MyForm />); renders the form element into the DOM asynchronously.
Note that the use of createRoot and render methods is a new feature of React 18. In earlier versions of React, we would use the ReactDOM.render() method to render a component synchronously.
To control the form using React we will need to introduce a new significant concept.


React components have two types of data: props and states. Props are passed to a component from its parent component and are read-only. A state on the other hand, is managed within the component itself.
Forms in React.js work by maintaining the state (aka, the condition) of a piece of data entered by our user. When a user interacts with an input field, such as typing in a text box or selecting a checkbox, React.js updates the state of the field which corresponds to the form. This allows the application to keep track of the user's input real-time.
Now, in HTML, the form data is usually handled by the DOM. However in React, it is the components that update the state with event handlers called in response to the user input.
For example, if we have a component whose function is to be a counter, the state could keep track of the current count. Each time the user clicks a button, the state could be updated to reflect the new count. The code for such a component might look like:
notion image
You may have noticed the useState hook being used in the code above. useState allows us to define a state variable and a function to update that variable. When the user activates an input field, the onChange event is triggered, which in turn calls the update function to update the state variable.
Another common method is the setState method, used to update the state of a component within class components. The useState hook is, in contrast, used to define state variables and update functions in function components.
The onSubmit attribute is an event handler which specifies a function to be called when a form is submitted. This contains information about the form submission, including the values of the forms inputs.
For example:
notion image

In Summary

A few common commands for state management include:
  1. useState: used to create a state variable, which is able to hold the value of an input element, and its corresponding setter function, used to update the state variable with changes in input.
  1. onChange: used to specify a function that is called whenever the value of an input element changes.
  1. onSubmit: used to specify a function that is called when a form is submitted.
Using state variables to hold the current values of input elements and setter functions to update the state variables helps us keep track of form state and respond to changes in real-time!

Control Components

Create a new class called AboutMe. In the main method, print your name. On the same line, print any message. On the next line(s), print a stanza from your favorite poem. Make sure it's formatted correctly. And of course, be sure to have good programming style!
In HTML, form elements like <input>, <textarea>, and <select> keep their own state based on user input. Remember how in React, state is stored in the state property of components and updated using setState(). React.js provides a built-in mechanism for controlling form input called "controlled components".
Controlled components are form elements that derive their values from React's state, rather than from the DOM; the state of the form is always in sync with the user's input.
The parent component passes down a value and an onChange function to the control component, which uses them to set the initial value of the input and to update the parent component's state with the current input value.
To use controlled components in React.js, we’ll need to define a state object along with event handlers–called properties, or props for short–that update the state object with the user's input for each form field. We’ll then need to bind the value of each form field to the corresponding property in the state object, so that React can keep track of the user's input.
For example:
notion image
In the code above, we're using a controlled component to handle the input field for the user's name. The value of the input field is controlled by the name state variable and updated by the setName function which is triggered by the onChange event handler. When the form is submitted, the handleSubmit function is called and an alert message is displayed with the user's name.
In this example, we used a functional component–a component that’s defined as a JavaScript function and hooks to fulfill our purpose; the ‘value’ of the input field is controlled by the ‘value’ property of the component's state, and updated by a handleChange function.
Another way to use control components would be using a JavaScript class. To define a class component, we extend the React.Component class and use the mandatory render() method. However, class components are primarily a function of pre-React 16.8 and have been largely superseded by functional components with hooks.

Uncontrolled components

We have controlled components, whose states are controlled by a parent component and who receive their current value and an update callback via props. Now we have uncontrolled components, who maintain their own states–its value is managed by the DOM rather than by React's state.
This means  instead of relying on state updates or event handlers to manage its value, the value of the input element is read from the DOM whenever needed. This can be useful for simple forms when we need to access the input value imperatively (e.g, integrating with non-React code).
A quick comparison between controlled and uncontrolled components:
notion image
For example, the following code for an uncontrolled component:
notion image
Notice how the value of the input field is not managed by React state, but rather by the input field itself using a ref attribute. The useRef hook is used to create a reference to the input field, which is then used to get its value when the form is submitted.

Previous Section

Next Section

Copyright © 2021 Code 4 Tomorrow. All rights reserved. The code in this course is licensed under the MIT License. If you would like to use content from any of our courses, you must obtain our explicit written permission and provide credit. Please contact classes@code4tomorrow.org for inquiries.