HTML form elements work a bit differently from other DOM elements in React, because form elements naturally keep some internal state. For example, below form in plain HTML accepts a single name
<form>
<label>
Name:
<input type="text" name="name" />
</label>
<input type="submit" value="Submit" />
</form>
In HTML, form elements such as
typically maintain their own state and update it based on user input.
In React, mutable state is typically kept in the state property of components, and only updated with setState().
Above form has the default HTML form behavior of browsing to a new page when the user submits the form. If you want this behavior in React, it just works. But in most cases, it’s convenient to have a JavaScript function that handles the submission of the form and has access to the data that the user entered into the form. The standard way to achieve this is with a technique called “controlled components”.
We can combine the two by making the React state be the “single source of truth”. Then the React component that renders a form also controls what happens in that form on subsequent user input. An input form element whose value is controlled by React in this way is called a “controlled component”.
Handling forms is about how you handle the data when it changes value or gets submitted.
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={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
</form>
)
}
export default MyForm;
You can control the values of more than one input field by adding a name attribute to each element
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>
<label>Enter your last name:
<input
type="text"
value={lname}
onChange={(e) => setName(e.target.value)}
/>
</label>
</form>
)
}
export default MyForm;
In React textarea element is slightly different from HTMl textarea.
In HTML the value of a textarea was the text 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. We'll use the useState Hook to mange the value of the textarea:
import { useState } from "react";
import ReactDOM from "react-dom";
function MyForm() {
const [textarea, setTextarea] = useState(
"The content of a textarea goes in the value attribute"
);
const handleChange = (event) => {
setTextarea(event.target.value)
}
return (
<form>
<textarea value={textarea} onChange={handleChange} />
</form>
)
}
export default MyForm;
<select> create a drop-down list in HTML
<select>
<option value="audi">Audi</option>
<option value="ford">Ford</option>
<option selected value="tata">Tata</option>
<option value="volvo">Volvo</option>
</select>
The selected value is defined with a value attribute on the select tag:
import { useState } from "react";
import ReactDOM from "react-dom";
function MyForm() {
const [myCar, setMyCar] = useState("Tata");
const handleChange = (event) => {
setMyCar(event.target.value)
}
return (
<form>
<select value={myCar} onChange={handleChange}>
<option value="Audi">Audi</option>
<option value="Ford">Ford</option>
<option value="Tata">Tata</option>
<option value="Volvo">Volvo</option>
</select>
</form>
)
}
export default MyForm;
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, [name]: value}))
}
const handleSubmit = (event) => {
event.preventDefault();
alert(inputs);
}
return (
<form onSubmit={handleSubmit}>
<label>Enter your name:
<input
type="text"
name="username"
value={inputs.username || ""}
onChange={handleChange}
/>
</label>
<label>Enter your age:
<input
type="number"
name="age"
value={inputs.age || ""}
onChange={handleChange}
/>
</label>
<input type="submit" />
</form>
)
}
export default MyForm ;
We know how important is doing the Validation of the Entered data before we do any operations using that data.
Formik is a small group of React components and hooks for building forms in React and React Native. It helps with the three most annoying parts:
Let's Assuming that Our Form has total five inputs, Id, name, Location, Salary and EmailId and we want validate Employee Name, Employee Location and Employee Email ID.
import React from 'react';
import ReactDOM from 'react-dom';
import {useFormik} from 'formik';
const validateEmployee = empData => {
const errors = {};
if (!empData.Name) {
errors.Name = 'Please Enter Employee Name';
} else if (empData.Name.length > 20) {
errors.Name = 'Name cannot exceed 20 characters';
}
if (!empData.Location) {
errors.Location = 'Please Enter Employee Location';
}
if (!empData.EmailId) {
errors.EmailId = 'Please Enter Email ID';
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(empData.EmailId)) {
errors.EmailId = 'Invalid email address';
}
return errors;
};
const EmployeeComponent=()=>{
const formik=useFormik({
initialValues:{
Id:'',
Name:'',
Location:'',
Salary:'',
EmailId:''
},
validate:validateEmployee,
onSubmit:values=>{
alert(JSON.stringify(values));
}
});
return (
<div>
<h2>New Employee Form...</h2>
<form onSubmit={formik.handleSubmit}>
<p>
<label htmlFor="Id">Employee ID : </label>
<input type="text" name="Id" id="Id" value={formik.values.Id}onChange={formik.handleChange}></input>
</p>
<p>
<label htmlFor="Name">Employee Name : </label>
<input type="text" name="Name" id="Name" value={formik.values.Name}
onChange={formik.handleChange} onBlur={formik.handleBlur}></input>
{formik.touched.Name && formik.errors.Name ? <span style={{color:'red'}}>
{formik.errors.Name}</span> : null}
</p>
<p>
<label htmlFor="Location">Employee Location : </label>
<input type="text" name="Location" id="Location" value={formik.values.Location}
onChange={formik.handleChange} onBlur={formik.handleBlur}></input>
{formik.touched.Location && formik.errors.Location ? <span style={{color:'red'}}>
{formik.errors.Location}</span> : null}
</p>
<p>
<label htmlFor="Salary">Employee Salary : </label>
<input type="text" name="Salary" id="Salary" value={formik.values.Salary}
onChange={formik.handleChange}></input>
</p>
<p>
<label htmlFor="EmailId">Employee Email ID : </label>
<input type="text" name="EmailId" id="EmailId" value=
{formik.values.EmailId}
onChange={formik.handleChange} onBlur={formik.handleBlur}></input>
{formik.touched.EmailId && formik.errors.EmailId ? <span style={{color:'red'}}>
{formik.errors.EmailId}</span> : null}
</p>
<button type="submit">Create</button>
</form>
</div>
)
}
const element=<EmployeeComponent></EmployeeComponent>
ReactDOM.render(element,document.getElementById("root"));
Regular expressions are patterns used to match character combinations in strings. In JavaScript, regular expressions are also objects. These patterns are used with the exec() and test() methods of RegExp, and with the match(), matchAll(), replace(), replaceAll(), search(), and split() methods of String.
You construct a regular expression in one of two ways
Using a regular expression literal, which consists of a pattern enclosed between slashes
let re = /ab+c/;
Regular expression literals provide compilation of the regular expression when the script is loaded. If the regular expression remains constant,
calling the constructor function of the RegExp object,
let re = new RegExp('ab+c');
The RegExp object is used for matching text with a pattern.
There are two ways to create a RegExp object: a literal notation and a constructor.
let re = /ab+c/i;
- constructor with string pattern as first argument
let re = new RegExp('ab+c', 'i')
- constructor with regular expression literal as first argument (Starting with ECMAScript 6)
let re = new RegExp(/ab+c/, 'i')
For more about RegExp