How to create a form in React using Formik and Yup-Beginners guide.
Today, we’ll learn how to create forms in React using formik and validate them using yup.
Have a look at what we are going to create today.
If I click on the submit button then the form should throw errors and the error will disappear after filling the value in the input.
let’s start with formik.
first, you have to create the react-app
npx create-react-app formik-form
then install formik and yup
npm i formik
npm i yup
Why do we require Formik…?
As we can create forms in react, it requires so much effort to manage the forms’ state, and if you are making a large form, then it will become very difficult to handle all the states mannualy in react.
What formik does…?
So first we look at the most elaborate way of creating forms using formik in react and validating them by using yup.
we’ll use the useFormik hook to create a form
useFormik hook helps us to manage the state, validation, and form submission.
so we are going to create a sign-up form
import React from 'react'
import { Formik, useFormik } from 'formik';
import * as Yup from 'yup'
const validateSchema = Yup.object().shape({
firstName:Yup.string().required('Name is required').min(2,'Name should contained 2 or more characters'),
lastName:Yup.string().required('Last name is required').min(2,'Last name should contained 2 or more characters'),
email:Yup.string().email('Invalid format').required('Email is required'),
password:Yup.string().required('Password is required').min(8,'Password length should be more then or equal to 8'),
});
const SignUp = () => {
const formik = useFormik({
initialValues:{
firstName:'',
lastName:'',
email:'',
password:'',
},
onSubmit:values=>{
console.log(values)
},
validationSchema:validateSchema
});
return (
<form onSubmit={formik.handleSubmit}>
<label htmlFor="firstName">First Name</label>
<input
type="text"
name='firstName'
value={formik.values.firstName}
onChange={formik.handleChange}
onBlur={formik.handleBlur}/>
{formik.touched.firstName && formik.errors.firstName && <div className='error'>{formik.errors.firstName}</div>}
<label htmlFor="lastName">Last Name</label>
<input
type="text"
name='lastName'
value={formik.values.lastName}
onChange={formik.handleChange}
onBlur={formik.handleBlur}/>
{formik.touched.lastName && formik.errors.lastName && <div className='error'>{formik.errors.lastName}</div>}
<label htmlFor="email">Email</label>
<input
type="email"
name='email'
value={formik.values.email}
onChange={formik.handleChange}
onBlur={formik.handleBlur}/>
{formik.touched.email && formik.errors.email && <div className='error'>{formik.errors.email}</div>}
<label htmlFor="password">Password</label>
<input
type="password"
name='password'
value={formik.values.password}
onChange={formik.handleChange}
onBlur={formik.handleBlur}/>
{formik.touched.password && formik.errors.password && <div className='error'>{formik.errors.password}</div>}
<button type='submit'>submit</button>
</form>
)
}
export default SignUp;
let’s break it down into some simple steps.
First, create a simple layout for the form.
import React from 'react'
import { Formik, useFormik } from 'formik';
import * as Yup from 'yup'
const SignUp = () => {
return (
<form>
<label htmlFor="firstName">First Name</label>
<input
type="text"
name='firstName'/>
<label htmlFor="lastName">Last Name</label>
<input
type="text"
name='lastName'/>
<label htmlFor="email">Email</label>
<input
type="email"
name='email'/>
<label htmlFor="password">Password</label>
<input
type="password"
name='password'/>
<button type='submit'>submit</button>
</form>
)
}
export default SignUp;
so here we have created a simple form that requires the user's first name, last name, email, and password.
Now let’s use useFormik hook to handle our form state
const formik = useFormik({
initialValues:{
firstName:'',
lastName:'',
email:'',
password:'',
},
onSubmit:values=>{
console.log(values)
},
validationSchema:validateSchema
});
useFormik return an object which we have stored in formik variable.
so here we have defined 3 things.
let’s declare validations for our form using yup
const validateSchema = Yup.object().shape(
firstName:Yup.string().required('Name is required').min(2,'Name should contained 2 or more characters'),
lastName:Yup.string().required('Last name is required').min(2,'Last name should contained 2 or more characters'),
email:Yup.string().email('Invalid format').required('Email is required'),
password:Yup.string().required('Password is required').min(8,'Password length should be more then or equal to 8'),
});
Here, I have added the validation using yup.
I have added the validation for the firstName should be a string and it’s required. A user cannot submit the form without filling in the first name and the min length is 2. That means the first name should be greater than or equal to two characters.
If the user submits the form without entering the first name it will show the error i.e. required
If the user enters a name that is greater than or equal to two characters. then the error will disappear.
this same method will follow for other fields as well for validation.
So far we’ve created the basic sign-up page, useFormik and validationSchema.
领英推荐
let’s add formik into our form
<form onSubmit={formik.handleSubmit}>
First added the handleSubmit which triggers the onSubmit to the form
After that, let’s add the properties to the input field as well.
<input
type="text"
name='firstName'
value={formik.values.firstName}
onChange={formik.handleChange}
onBlur={formik.handleBlur}/>
here we have set the value equal to the {formik.values.firstName}?and added the onChange handler and onBlur handler
{formik.handleChange}?will automatically handle the form’s value
{formik.handleBlur}?bascially help to know whether an input has been?touched?or not. if it is touched and it has error only show the error
let’s set the error for each field
<input
type="text" name='firstName'
value={formik.values.firstName}
onChange={formik.handleChange}
onBlur={formik.handleBlur}/>
{formik.touched.lastName && formik.errors.lastName &&
<div className='error'>{formik.errors.lastName}</div>}
Here we are looking for if the user has visited the input and entered the invalid data then show the error. You can added the error for each field like this.
So, now you have created the form using formik and yup ????
Now let’s refactor the code.
step-1: formik provided the alternative for?handleChange?,?handleBlur and value?which is formik.getFieldProps(‘name’). it takes the name of the input.
<input
type="text"
name='firstName'
{...formik.getFieldProps('firstName')} />
Now, updated code should look like this
<form onSubmit={formik.handleSubmit}
<label htmlFor="firstName">First Name</label>
<input
type="text"
name='firstName'
{...formik.getFieldProps("firstName")}
/>
{formik.touched.firstName && formik.errors.firstName && <div className='error'>{formik.errors.firstName}</div>}
<label htmlFor="lastName">Last Name</label>
<input
type="text"
name='lastName'
{...formik.getFieldProps("lastName")}
/>
{formik.touched.lastName && formik.errors.lastName && <div className='error'>{formik.errors.lastName}</div>}
<label htmlFor="email">Email</label>
<input
type="email"
name='email'
{...formik.getFieldProps("lastName")}
/>
{formik.touched.email && formik.errors.email && <div className='error'>{formik.errors.email}</div>}
<label htmlFor="password">Password</label>
<input
type="password"
name='password'
{...formik.getFieldProps("password")}
/>
{formik.touched.password && formik.errors.password && <div className='error'>{formik.errors.password}</div>}
<button type='submit'>submit</button>
</form>
step-2: Now, we’ll replace the useFormik hook with Formik component.
return (
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validationSchema={validateSchema}>
<Form>
<label htmlFor="firstName">First Name</label>
<input
type="text"
name='firstName'
{...formik.getFieldProps("firstName")}
/>
{formik.touched.firstName && formik.errors.firstName && <div className='error'>{formik.errors.firstName}</div>}
<label htmlFor="lastName">Last Name</label>
<input
type="text"
name='lastName'
{...formik.getFieldProps("lastName")}
/>
{formik.touched.lastName && formik.errors.lastName && <div className='error'>{formik.errors.lastName}</div>}
<label htmlFor="email">Email</label>
<input
type="email"
name='email'
{...formik.getFieldProps("lastName")}
/>
{formik.touched.email && formik.errors.email && <div className='error'>{formik.errors.email}</div>}
<label htmlFor="password">Password</label>
<input
type="password"
name='password'
{...formik.getFieldProps("password")}
/>
{formik.touched.password && formik.errors.password && <div className='error'>{formik.errors.password}</div>}
<button type='submit'>submit</button>
</Form>
</Formik>
)
5. replace the input by using Field component
import React from 'react'
import { Formik, Form, Field} from 'formik';
import * as Yup from 'yup'
const validateSchema = Yup.object().shape({
firstName:Yup.string().required('Name is required').min(2,'Name should contained 2 or more characters'),
lastName:Yup.string().required('Last name is required').min(2,'Last name should contained 2 or more characters'),
email:Yup.string().email('Invalid format').required('Email is required'),
password:Yup.string().required('Password is required').min(8,'Password length should be more then or equal to 8'),
});
const SignUp = () => {
const initialValues = {
firstName:'',
lastName:'',
email:'',
password:'',
}
const handleSubmit= values=>{
console.log(values)
}
return (
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validationSchema={validateSchema}>
<Form>
<label htmlFor="firstName">First Name</label>
<Field
type="text"
name='firstName'
/>
<label htmlFor="lastName">Last Name</label>
<Field
type="text"
name='lastName'
/>
<label htmlFor="email">Email</label>
<Field
type="email"
name='email'
/>
<label htmlFor="password">Password</label>
<Field
type="password"
name='password'
/>
<button type='submit'>submit</button>
</Form>
</Formik>
)
}
export default SignUp;
After that add the ErrorMessage component to show the error
import React from 'react'
import { Formik, Form, Field, ErrorMessage} from 'formik';
import * as Yup from 'yup'
const validateSchema = Yup.object().shape({
firstName:Yup.string().required('Name is required').min(2,'Name should contained 2 or more characters'),
lastName:Yup.string().required('Last name is required').min(2,'Last name should contained 2 or more characters'),
email:Yup.string().email('Invalid format').required('Email is required'),
password:Yup.string().required('Password is required').min(8,'Password length should be more then or equal to 8'),
});
const SignUp = () => {
const initialValues = {
firstName:'',
lastName:'',
email:'',
password:'',
}
const handleSubmit= values=>{
console.log(values)
}
return (
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validationSchema={validateSchema}>
<Form>
<label htmlFor="firstName">First Name</label>
<Field
type="text"
name='firstName'
/>
<ErrorMessage name='firstName'/>
<label htmlFor="lastName">Last Name</label>
<Field
type="text"
name='lastName'
/>
<ErrorMessage name='lastName'/>
<label htmlFor="email">Email</label>
<Field
type="email"
name='email'
/>
<ErrorMessage name='email'/>
<label htmlFor="password">Password</label>
<Field
type="password"
name='password'
/>
<ErrorMessage name='password'/>
<button type='submit'>submit</button>
</Form>
</Formik>
)
}
export default SignUp;
That’s all for code refactoring.
Now, you’ll see that your error message is no longer displayed in red color.
So, let’s display the error message in red color
Create a new file, I have named it TextError.jsx.
It automatically received some props from ErrorMessage component
import React from 'react
const TextError = ({children}) => {
return (
<div className='error'>{children}</div>
)
}
export default TextError'
Here I've added the class {error} to make the text red.
congratulations you did it ??????
Now you should have good understanding of formik
Hope you like this.
Happy coding!
want to give any suggestions:-
have a look at?my portfolio
Email me at [email protected]
--
6 个月can i used it with nextui