React forms are crucial in how users interact with websites and web applications. Validating the user’s data passed through the form is essential.
React Hook Form is a library that validates forms in React. It is a minimal library without any other dependencies. It is straightforward and performant and requires developers to write fewer lines of code compared to other form libraries.
This article below will highlight using the React Hook Form library to build amazing React forms without any complicated render props or higher-order components.
React Hook Form is a collection that facilitates the validation of forms in React. It is a small self-reliant library that performs its functions in a straightforward way necessitating the developers to write only a few lines of code compared to other libraries out there. Compared to HTML forms, the HTML forms perform slightly differently from React forms. Developers can attain expertise in React by joining the React training course
React Hook Form constructs forms that is easier to use. Developers can implement forms with fewer lines of code. It has excellent performance and is precise to use and implement custom forms.
React Hook Forms utilize ref instead of component states. It lessens re-rendering and gives better performance.
You can access Official React Hook Form Library as below:
- Package (react-hook-form@7.17.1) size is 8.2 kb
- No dependencies on other libraries
- It has great TypeScript support
To install React Hook Form use the existing application:
npm install react-hook-form
Let us learn the fundamentals of the useForm Hook by creating a basic registration form.
Import the useForm Hook from the react-hook-form package:
Let us learn the fundamentals of the useForm Hook by creating a basic registration form.
Import useForm Hook from the react-hook-form package
import { useForm } from "react-hook-form";
Use the Hook as follows:
const { register, handleSubmit } = useForm();
The useForm Hook containing a few properties returns an object. Only register and handleSubmit are required for now.
The register method aids in registering an input field into React Hook Form
To register the input, the register method is passed into the input field as follows:
<input type="text" name="firstName" {...register('firstName')} />
This syntax of the spread operator is a new implementation to the library that enables strict type checking in forms with TypeScript.
Versions older than v7 had the register method attached to the ref attribute as such:
<input type="text" name="firstName" ref={register} />
As the name handleSubmit method suggests, it manages form submission. It should be passed as the value to the onSubmit prop of the form component.
The handleSubmit method handles two functions as arguments. The first function argument will invoke the registered field values when the form validation is successful. The second function calls errors when the validation fails.
const onFormSubmit = data => console.log(data);
const onErrors = errors => console.error(errors);
<form onSubmit={handleSubmit(onFormSubmit, onErrors)}>
{/* ... */}
</form>
Let's have a realistic example:
import React from "react";
import { useForm } from "react-hook-form";
const RegisterForm = () => {
const { register, handleSubmit } = useForm();
const handleRegistration = (data) => console.log(data);
return (
<form onSubmit={handleSubmit(handleRegistration)}>
<div>
<label>Name</label>
<input name="name" {...register('name')} />
</div>
<div>
<label>Email</label>
<input type="email" name="email" {...register('email')} />
</div>
<div>
<label>Password</label>
<input type="password" name="password" {...register('password')} />
</div>
<button>Submit</button>
</form>
);
};
export default RegisterForm;
The useForm Hook above makes the component code cleaner and easier to maintain. The form is uncontrolled, and it is not necessary to pass props like onChange and value to each input.
Use any other UI library of your choice for creating the form. Check the docs, and find the prop used for accessing the reference attribute of the native input component.
- Handling forms is handling the data when it alters the value or submits data.
- Form data is regulated by the DOM in In HTML.
- The components in React control the form data.
- When the components handle the data in react, the information is accumulated in the component state.
- On the onChange attribute, changes are driven by adding event handlers.
- useState Hook can maintain track of input values and deliver a "single source of truth" for the complete application.
- We have a Form tag and labels for the inputs as is written in HTML.
- In React, all labels have htmlFor prop related input that matches id, and in HTML, the label attribute is used
- React has constraints, and the way forms work is borrowed from HTML and the DOM.
Inputs in React can be of two types: controlled or uncontrolled.
Uncontrolled Components: Components that are not controlled by the React state and are handled by the DOM (Document Object Model). To access any value entered, we take the help of refs.
Adding a file as an input cannot be controlled as this depends on the browser is an example of an uncontrolled input.
Creating React Application
Step 1: Using the following command, create an application
npm create-react-app project
Step 2: Move to the project folder by using the following command:
cd project
import React, { useRef } from 'react';
function App() {
const inputRef = useRef(null);
function handleSubmit() {
alert(`Name: ${inputRef.current.value}`);
}
return (
<div className="App">
<h3>Uncontrolled Component</h3>
<form onSubmit={handleSubmit}>
<label>Name :</label>
<input type="text" name="name" ref={inputRef} />
<button type="submit">Submit</button>
</form>
</div>
);
}
export default App;
Step to Run Application: Run the application using the following command from the root directory of the project:
npm start
Creating a form that includes an input field with a label name and a submit button. onSubmit function triggers when we submit the form, which displays the name we have filled in the alert box.
Controlled Components: Controlled Components are form data handled by the component’s state. It takes its current value through props and makes modifications through callbacks like onClick, onChange, etc.
Example: Creating a form that comprises an input field with a label name and a submit button. onSubmit function triggers when the form is submitted. It shows the name that we have filled in the alert box.
import { useState } from 'react';
function App() {
const [name, setName] = useState('');
function handleSubmit() {
alert(`Name: ${name}`);
}
return (
<div className="App">
<h3>Controlled Component</h3>
<form onSubmit={handleSubmit}>
<label>Name:</label>
<input name="name" value={name} onChange={(e) => setName(e.target.value)} />
<button type="submit">Submit</button>
</form>
</div>
);
}
export default App;
Step to Run Application: Run the application using the following command from the root directory of the project:
npm start
Difference between Controlled and Uncontrolled Components:
Controlled | Uncontrolled |
The Component is in the control of the Component’s state. | The Component is in the control of DOM. |
Components are predictable as they are managed by the state of the Component. | During the life cycle methods, the data may be lost as they are uncontrolled |
The internal state is not sustained | The internal state is held |
The current value is accepted as props | Access the values utilizing refs |
It doesn't preserve the internal state. | It maintains the internal state. |
It is controlled by the parent component. | It is controlled by the DOM itself. |
When and Why to Use Controlled Inputs
Controlled inputs are the “React-y way” of doing things, where UI contemplates state. By altering the state, you change the UI. If you don’t alter the state, the UI stays the same.
Controlled inputs are perfect for things like:
- Immediately validating the form on every keypress is helpful if the Submit button is disabled until everything is valid.
- Regulating formatted input, like a credit card number field, averts specific characters from being typed.
- Keeping considerable inputs in sync with each other when they are dependent on the identical data
- There are multiple use cases where it is essential to react to every keypress and handle it somehow.
Controlled inputs are good for that.
- Controlled Inputs are More Complex
- The manually handled input value means (a) state to hold it and (b) a change handler function, and all needs are required for every input.
Are you looking for the best course material to learn React topics from scratch? Check out complete web development course and get guidance from experts and industry professionals.
Following are the ways to build forms in React.js
Building Forms common in any web application development. Unlike Angular, which give form validation out of the box, we have to handle forms ourselves in React.
Complications include as follows
- How to obtain form values.
- How to handle the form state.
- Validating the form on the fly.
- How to display validation messages.
In HTML, form elements such as <input>, <textarea>, and <select> maintain their state and update it based on user inputs.
In React, the state of these input elements is generally kept in the state property of components and updated with setState().
Prerequisites
- A development environment running Node.js is required; To install this on macOS or Ubuntu 18.04, pursue the steps in How to Install Node.js and Construct a Local Development Environment on macOS or the Installing Using a PPA section of How To Install Node.js on Ubuntu 18.04.
- A React development environment materialized and set.
- Follow Step 1 — Creating an Empty Project of the How To Organize State on React Class Components tutorial to set this up.
- React events and Hooks include the useState and the useReducer Hooks.
- Knowledge of JavaScript and HTML is required to build a Website with HTML series and how to code in JavaScript.
Adding Forms in React
In HTML, React uses forms to authorize users to interact with the web pages.
Adding forms in React like any other element:
function MyForm() {
return (
<form>
<label>Enter your First Name:
<input type="text" />
</label>
</form>
)
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
As usual, the above form would work, as usual, the form is submitted, and the page will refresh.
We would like to prevent the default behavior and allow React to control the form.
Handling Forms
React form is handled differently compared to regular HTML. The form inputs are maintained by DOM, But in React, we are in charge of handling these inputs. The form data is handled by the DOM in HTML and in react the data is handled by the components.
Below example shows useState() as a Hook that allows to have state variables in functional components
import { useState } from "react";
import ReactDOM from 'react-dom';
function MyForm() {
const [name, setName] = useState("");
return (
<form>
<label>Enter your First Name:
<input type="text" value={fname}
onChange={(e) => setName(e.target.value)} />
</label>
</form>
)
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Submitting Forms
By adding an event handler within the onSubmit attribute for the <form> tag, the submit action can be controlled
import { useState } from "react";
import ReactDOM from 'react-dom';
function MyForm() {
const [name, setName] = useState("");
const handleSubmit = (event) => {
event.preventDefault();
alert(`The First name you entered was: ${fname}`)
}
return (
<form onSubmit={handleSubmit}>
<label>Enter your First Name:
<input
type="text"
value={fname}
onChange={(e) => setName(e.target.value)}
/>
</label>
<input type="submit" />
</form>
)
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Multiple Input Fields
- By Adding a name attribute to each element for more than one input field the values from each from multiple field can be controlled
- Empty object would be used to initialize the state
- Use event.target.name and event.target.value syntax to retrieve values from the fields
- Add square brackets [bracket notation around the property name to update the state
import { useState } from "react";
import ReactDOM from "react-dom";
function MyForm() {
const [inputs, setInputs] = useState({});
const handleChange = (event) => {
const name = event.target.name;
const value = event.target.value;
setInputs(values => ({...values, [fname]: value}))
}
const handleSubmit = (event) => {
event.preventDefault();
alert(inputs);
}
return (
<form onSubmit={handleSubmit}>
<label>Enter your First Name:
<input
type="text"
name="fname"
value={inputs.fname || ""}
onChange={handleChange}
/>
</label>
<label>Enter your Last Name:
<input
type="text"
name="lname"
value={inputs.lname || ""}
onChange={handleChange}
/>
</label>
<input type="submit" />
</form>
)
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Textarea
The textarea component in React is a little different from what we have in ordinary HTML.
In HTML the value of a textarea would appear what text is in between the start tag <textarea> and the end tag </textarea>.
<textarea>
Content of the textarea.
</textarea>
In React, the value of a textarea is placed in a value attribute. Use the useState Hook to regulate and manage the value of the textarea:
import { useState } from "react";
import ReactDOM from "react-dom";
function MyForm() {
const [textarea, setTextarea] = useState(
"The textarea has content that can go viral"
);
const handleChange = (event) => {
setTextarea(event.target.value)
}
return (
<form>
<textarea value={textarea} onChange={handleChange} />
</form>
)
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Select
In React, a drop-down list or a select box is different from normal HTML.
HTML: The selected value in the drop down list defines the selected attribute:
<select>
<option value="Maruti">Maruti</option>
<option value="Hyundai" selected>Hyundai</option>
<option value="Kia">Kia</option>
</select>
React: In select tag, the selected value is specified with a value attribute:
function MyForm() {
const [myCar, setMyCar] = useState("Kia");
const handleChange = (event) => {
setMyCar(event.target.value)
}
return (
<form>
<select value={myCar} onChange={handleChange}>
<option value="Maruti">Maruti</option>
<option value="Hyundai" selected>Hyundai</option>
<option value="Kia">Kia</option>
</select>
</form>
)
}
React can handle all input elements simultaneously by implementing these changes to <textarea> and <select> fields.
Form elements like <input>, <textarea>, and <select> in HTML are maintained and updated based on user input. In React, mutable (an object whose state can be modified after it is created) state is placed in the components, and is updated using setState() hook.
The React element that renders a form on subsequent user inputs also affects the state. A form input element whose value is controlled by React is called a “controlled component.”
E.g., Below is the example of form as a controlled component:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) { this.setState({value: event.target.value}); }
handleSubmit(event) {
alert('Person's name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>Name:<input type="text" value={this.state.value}
onChange={this.handleChange} /></label>
<input type="submit" value="Submit" />
</form>
);
}
}
Using React Hooks – Alternate Method
React Hooks are in-built functions and they help developers to use state in functional components. Hooks are powerful.
React Developers enjoy the following benefits:
- Enhanced code reuse;
- Better code formatting;
- More acceptable defaults;
- Sharing non-visual logic with the usage of custom hooks;
- Flexibility in moving up and down the element tree.
Developers gain the power to use functional components for almost everything they need to do, from just rendering UI to handling state and logic.
import React, { useState } from "react";
import ReactDOM from "react-dom";
function FavoriteColor() {
const [color, setColor] = useState("blue");
return (
<>
<h1>My favorite color is {color}!</h1>
<button
type="button"
onClick={() => setColor("purple")}
>Blue</button>
<button
type="button"
onClick={() => setColor("blue")}
>Red</button>
<button
type="button"
onClick={() => setColor("black")}
>Pink</button>
<button
type="button"
onClick={() => setColor("green")}
>Green</button>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<FavoriteColor />);
According to the ReactJS official documentation, below are the advantages of using React Hooks:
Reusing Stateful Logic
It becomes simple to reuse logic between your components with Hooks without changing their architecture or structure.
Complex Components
When components evolve and become more extensive and carry out many operations, it becomes challenging to understand in the long run. Hooks solve this by authorizing it to separate a particular single component into various smaller functions instead of having to force a split based on lifecycle methods.
Confusing Classes
Classes are a barrier to learning React properly; you need to understand how JavaScript varies from other languages. React Hooks cracks this problem by authorizing developers to use the best of React features without using classes.
Conclusion
This is just the tip of an iceberg when we start working forms with React Hook Form. With its easy-to-go syntax and great features, you can also use it with TypeScript, create wizard-like multiple forms and even use their online form builder where you add the elements you want along with rules and bam! You get your generated code in one click.
In Multi-step form example Formik revamped it when there were modifications in the input as React Hooks prevented the form from re-rendering a single field modification. Undoubtedly less code would be written with Formik as only one component is generated and with React hook form three components are generated which would affect performance because of the re-renders. Formik can be helpful when we want implement in-place validation and provide a specific input format. React hook form is perfect and excellent for simple forms as it does not have any dependencies. In the end, both libraries are helpful and beneficial to execute forms with React.
Knowledgehut training programs help individuals move into more elevated and higher roles and handle more responsibilities in an organization. These programs help learn the skills required to function effectively in their new positions.
Enrolling in React training Knowledgehut, we can expect immersive and extensive training experience from their certified trainers. The React course would help developers expect a rewarding career as a developer.