In this tutorial, I will show you how to implement React Form Validation and Submit example using Formik, Yup and Bootstrap 4.
More Practice:
– React Custom Hook
– React Hooks: CRUD example with Rest API
– React Hooks File Upload example with Axios & Progress Bar
– React Hooks: JWT Authentication (without Redux) example
– React Hooks + Redux: JWT Authentication example
Serverless:
– React Hooks + Firebase Realtime Database: CRUD App
– React Hooks + Firestore example: CRUD app
Using React Hook Form instead:
React Form Validation with Hooks, Bootstrap | react-hook-form 7
Contents
Overview of React Hooks Form Validation example
We will implement validation for a React Form using Formik and Bootstrap 4 with React Hooks. The form has:
- Full Name: required
- Username: required, from 6 to 20 characters
- Email: required, email format
- Password: required, from 6 to 40 characters
- Confirm Password: required, same as Password
- Accept Terms Checkbox: required
Some fields could be wrong:
Successful Submission will look like this:
Technology
We’re gonna use following modules:
- react 17/16
- bootstrap 4
- formik 2
- yup
Setup Project
First we need to install necessary modules.
Open your project root folder, run the command:
npm install formik yup
# Or:
yarn add formik yup
Open package.json, the dependencies will look like this:
{
"name": "react-form-validation-example",
"version": "0.1.0",
"private": true,
"dependencies": {
...
"formik": "^2.2.9",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"yup": "^0.32.9"
},
...
}
Import Bootstrap
Open public/index.html and add following line to <head>
tag:
<!DOCTYPE html>
<html lang="en">
<head>
...
<link href="//netdna.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet" />
...
<title>React Hooks Form Validation example</title>
</head>
<body>
...
<div id="root"></div>
</body>
</html>
Or you can run command: npm install bootstrap
.
Then open src/App.js and modify the code inside it as following-
import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
function App() {
return (
...
);
}
export default App;
React Hooks Form Validation example with Formik
The app component contains Form Validation example built with Formik and Yup library.
Formik, together with Yup, help handling forms conveniently in React. With Yup, we can create schema for validation abstractly instead of creating custom validation for each input field.
You need to notice following important Formik attributes:
initialValues
validationSchema
onSubmit
Open src/App.js, we’re gonna import necessary library first:
import React from 'react';
import { useFormik } from "formik";
import * as Yup from 'yup';
Next we use Yup schema validation library for Form validation rules:
function App() {
const validationSchema = Yup.object().shape({
fullname: Yup.string().required("Fullname is required"),
username: Yup.string()
.required("Username is required")
.min(6, "Username must be at least 6 characters")
.max(20, "Username must not exceed 20 characters"),
email: Yup.string().required("Email is required").email("Email is invalid"),
password: Yup.string()
.required("Password is required")
.min(6, "Password must be at least 6 characters")
.max(40, "Password must not exceed 40 characters"),
confirmPassword: Yup.string()
.required("Confirm Password is required")
.oneOf([Yup.ref("password"), null], "Confirm Password does not match"),
acceptTerms: Yup.bool().oneOf([true], "Accept Terms is required"),
});
...
}
Next, instead of managing our form’s values with custom event handlers for every single input, we can just use useFormik() which is a custom React hook. It will return all Formik state and helpers directly.
function App() {
...
const formik = useFormik({
initialValues: {
fullname: "",
username: "",
email: "",
password: "",
confirmPassword: "",
acceptTerms: false,
},
validationSchema,
// validateOnChange: false,
// validateOnBlur: false,
onSubmit: (data) => {
console.log(JSON.stringify(data, null, 2));
},
});
...
}
– initialValues
: object for initial values of the form fields. Each key of the object must correspond with the name
of the Formik input
field.
– validationSchema
: function for handling validation. It receives form data values and validates each property based on the rules defined. Each key of the object must correspond with the name
of the Formik input
field.
– onSubmit
: function for handling submission. It receives callback function that will run when the validation has passed without any error.
You can also trigger validation only on form submit by setting validateOnChange
and validateOnBlur
to false
.
React Hooks Form Validation with Formik template
Now we create the form with input fields and validation messages.
function App() {
...
return (
<div className="register-form">
<form onSubmit={formik.handleSubmit}>
<div className="form-group">
<label>Full Name</label>
<input
name="fullname"
type="text"
className={
'form-control' +
(formik.errors.fullname && formik.touched.fullname
? ' is-invalid'
: '')
}
onChange={formik.handleChange}
value={formik.values.fullname}
/>
<div className="invalid-feedback">
{formik.errors.fullname && formik.touched.fullname
? formik.errors.fullname
: null}
</div>
</div>
<div className="form-group">
<label htmlFor="username"> Username </label>
<input
name="username"
type="text"
className={
'form-control' +
(formik.errors.username && formik.touched.username
? ' is-invalid'
: '')
}
onChange={formik.handleChange}
value={formik.values.username}
/>
<div className="invalid-feedback">
{formik.errors.username && formik.touched.username
? formik.errors.username
: null}
</div>
</div>
<div className="form-group">
<label htmlFor="email"> Email </label>
<input
name="email"
type="email"
className={
'form-control' +
(formik.errors.email && formik.touched.email ? ' is-invalid' : '')
}
onChange={formik.handleChange}
value={formik.values.email}
/>
<div className="invalid-feedback">
{formik.errors.email && formik.touched.email
? formik.errors.email
: null}
</div>
</div>
<div className="form-group">
<label htmlFor="password"> Password </label>
<input
name="password"
type="password"
className={
'form-control' +
(formik.errors.password && formik.touched.password
? ' is-invalid'
: '')
}
onChange={formik.handleChange}
value={formik.values.password}
/>
<div className="invalid-feedback">
{formik.errors.password && formik.touched.password
? formik.errors.password
: null}
</div>
</div>
<div className="form-group">
<label htmlFor="confirmPassword"> Confirm Password </label>
<input
name="confirmPassword"
type="password"
className={
'form-control' +
(formik.errors.confirmPassword && formik.touched.confirmPassword
? ' is-invalid'
: '')
}
onChange={formik.handleChange}
value={formik.values.confirmPassword}
/>
<div className="invalid-feedback">
{formik.errors.confirmPassword && formik.touched.confirmPassword
? formik.errors.confirmPassword
: null}
</div>
</div>
<div className="form-group form-check">
<input
name="acceptTerms"
type="checkbox"
className={
'form-check-input' +
(formik.errors.acceptTerms && formik.touched.acceptTerms
? ' is-invalid'
: '')
}
onChange={formik.handleChange}
value={formik.values.acceptTerms}
/>
<label htmlFor="acceptTerms" className="form-check-label">
I have read and agree to the Terms
</label>
<div className="invalid-feedback">
{formik.errors.acceptTerms && formik.touched.acceptTerms
? formik.errors.acceptTerms
: null}
</div>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary">
Register
</button>
<button
type="button"
className="btn btn-warning float-right"
onClick={formik.handleReset}
>
Reset
</button>
</div>
</form>
</div>
);
}
export default App;
– handleSubmit
: submission handler
– handleChange
: change handler to pass to each <input>
– values
: form’s current values
– handleReset
: reset handler or using <button type="reset">
You can see that we use the name
attribute to match up with Formik state.
Remember that <Field>
, <ErrorMessage>
… will NOT work with useFormik()
because they require React Context.
Run React Form Validation example
You can run our App with command: yarn start
or npm run start
.
If the process is successful, open Browser with Url: http://localhost:3000/
and check it.
Or run on Stackblitz:
Conclusion
Today we’ve built a React Form Validation example successfully using React Hooks, Formik, Yup & Bootstrap 4.
You can also implement this Form Validation in following posts:
– React Hooks: CRUD example with Rest API
– React Hooks: JWT Authentication (without Redux) example
– React Hooks + Redux: JWT Authentication example
Further Reading
– React Custom Hook
– React Hooks File Upload example with Axios & Progress Bar
– React Pagination using Hooks example
Serverless with Firebase:
– React Hooks + Firebase Realtime Database: CRUD App
– React Hooks + Firestore example: CRUD app
Fullstack:
– React + Spring Boot + MySQL: CRUD example
– React + Spring Boot + PostgreSQL: CRUD example
– React + Spring Boot + MongoDB: CRUD example
– React + Node.js + Express + MySQL: CRUD example
– React + Node.js + Express + PostgreSQL example
React Redux + Node.js + Express + MySQL: CRUD example
– React + Node.js + Express + MongoDB example
– React + Django + Rest Framework example
This worked very well for me. Thanks for the tutorial!
would love to always read tutorials from your site.