React + Formik - Form Validation Example
Example built with React 16.8.6 and Formik 1.5.2
Other versions available:
- Angular Reactive Forms: Angular 14, 10, 9, 8, 7, 6
- Angular Template-Driven Forms: Angular 14, 10, 9, 8, 7, 6
- Blazor: Blazor WebAssembly
- Next.js: Next.js
- React + Formik: Formik 2
- React Hook Form: React Hook Form 7, 6
- Vue + VeeValidate: Vue 3 Composition API, Vue 3 Options API, Vue 2
- Vue + Vuelidate: Vue 2
This is a quick example of how to setup form validation in React with the Formik library. Formik contains a higher order component that helps with managing react state, validation, error messages and form submission. Validation is done with the Yup object schema validator which hooks into Formik via the handy validationSchema
prop.
The example is a simple registration form with pretty standard fields for first name, last name, email, password and confirm password. All fields are required, the email field must be a valid email address, the password field must have a min length of 6 and must match the confirm password field.
Styling of the React + Formik example is all done with Bootstrap 4 CSS.
Here it is in action: (See on StackBlitz at https://stackblitz.com/edit/react-formik-form-validation)
React + Formik Form Validation App Component
The app component contains an example registration form built with the <Formik />
component. The initial values of each field are set in the initialValues
property. Validation rules and error messages are set in the validationSchema
property. The onSubmit
property contains a function that gets called when the form is submitted and valid. The html and jsx markup for the form is set in the render
property.
The <Field />
and <ErrorMessage />
components are part of the Formik library that automatically hook up inputs and error messages with the fields defined in Formik. For more info about the helper components available check out the Formik docs.
import React from 'react';
import { Formik, Field, Form, ErrorMessage } from 'formik';
import * as Yup from 'yup';
class App extends React.Component {
render() {
return (
<Formik
initialValues={{
firstName: '',
lastName: '',
email: '',
password: '',
confirmPassword: ''
}}
validationSchema={Yup.object().shape({
firstName: Yup.string()
.required('First Name is required'),
lastName: Yup.string()
.required('Last Name is required'),
email: Yup.string()
.email('Email is invalid')
.required('Email is required'),
password: Yup.string()
.min(6, 'Password must be at least 6 characters')
.required('Password is required'),
confirmPassword: Yup.string()
.oneOf([Yup.ref('password'), null], 'Passwords must match')
.required('Confirm Password is required')
})}
onSubmit={fields => {
alert('SUCCESS!! :-)\n\n' + JSON.stringify(fields, null, 4))
}}
render={({ errors, status, touched }) => (
<Form>
<div className="form-group">
<label htmlFor="firstName">First Name</label>
<Field name="firstName" type="text" className={'form-control' + (errors.firstName && touched.firstName ? ' is-invalid' : '')} />
<ErrorMessage name="firstName" component="div" className="invalid-feedback" />
</div>
<div className="form-group">
<label htmlFor="lastName">Last Name</label>
<Field name="lastName" type="text" className={'form-control' + (errors.lastName && touched.lastName ? ' is-invalid' : '')} />
<ErrorMessage name="lastName" component="div" className="invalid-feedback" />
</div>
<div className="form-group">
<label htmlFor="email">Email</label>
<Field name="email" type="text" className={'form-control' + (errors.email && touched.email ? ' is-invalid' : '')} />
<ErrorMessage name="email" component="div" className="invalid-feedback" />
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<Field name="password" type="password" className={'form-control' + (errors.password && touched.password ? ' is-invalid' : '')} />
<ErrorMessage name="password" component="div" className="invalid-feedback" />
</div>
<div className="form-group">
<label htmlFor="confirmPassword">Confirm Password</label>
<Field name="confirmPassword" type="password" className={'form-control' + (errors.confirmPassword && touched.confirmPassword ? ' is-invalid' : '')} />
<ErrorMessage name="confirmPassword" component="div" className="invalid-feedback" />
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary mr-2">Register</button>
<button type="reset" className="btn btn-secondary">Reset</button>
</div>
</Form>
)}
/>
)
}
}
export { App };
React + Formik Form Validation Index HTML File
The base index html file contains the outer html for the whole tutorial application.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React + Formik - Form Validation Example</title>
<!-- bootstrap css -->
<link href="//netdna.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" />
<style>
a { cursor: pointer; }
</style>
</head>
<body>
<div class="jumbotron">
<div class="container">
<div class="row">
<div class="col-md-6 offset-md-3">
<h3>React + Formik - Form Validation</h3>
<div id="app"></div>
</div>
</div>
</div>
</div>
</body>
</html>
React + Formik Form Validation Main Entry File
The root index.jsx file bootstraps the react tutorial application by rendering the App
component into the #app
div element defined in the base index html file above.
import React from 'react';
import { render } from 'react-dom';
import { App } from './App';
render(
<App />,
document.getElementById('app')
);
Need Some React Help?
Search fiverr for freelance React developers.
Follow me for updates
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!