Manage Forms In React With Formik

Managing forms in any application requires the following things,
  • Updating state value on form control change.
  • Updating touched / errors state for form control to show required messages.
  • Form Validation.
  • Updating form state like dirty and valid.
In React it is a bit complex to manage these things, we need to manage each thing manually using state. There are many popular libraries available to manage these things. In this article, we will see one such library, Formik - one of the popular libraries for managing forms in React.
 

Formik


Formik provides all the required features out-of-the-box for managing forms,
  • Initializing form state
  • Updating value state on control value changes
  • Updating errors / touched state on form control change
  • Handler function like handleBlur, handleChange which updates the form state, handleSubmit which calls the onSubmit handler on form submit
  • Form validation mechanism
  • Form state like valid, dirty, submitting count
and many more. So let's get started, I am using online editor stackblitz for this sample application.

We will create a registration form and manage its state with Formik.
 

Setup Form Template

 
Let's first set up the registration form template as shown below,
 
Registration Form Template

You can create this form in any component, I have created it in App.js/App.jsx. 
  1. // App.js / App.jsx  
  2.   
  3. import React from 'react';  
  4. import './style.css';  
  5.   
  6. export default function App() {  
  7.   return (  
  8.     <div class="root">  
  9.       <div class="form">  
  10.         <h1> Registration </h1>  
  11.         <form>  
  12.           <div class="form-group">  
  13.             <label> First Name </label>  
  14.             <input type="text" />  
  15.           </div>  
  16.           <div class="form-group">  
  17.             <label> Last Name </label>  
  18.             <input type="text" />  
  19.           </div>  
  20.           <div class="form-group">  
  21.             <label> Email Id </label>  
  22.             <input type="text" />  
  23.           </div>  
  24.           <div class="form-group">  
  25.             <label> Mobile Number </label>  
  26.             <input type="text" />  
  27.           </div>  
  28.           <div class="form-group">  
  29.             <label> Gender </label>  
  30.             <select>  
  31.               <option value="">Select</option>  
  32.               <option value="male">Male</option>  
  33.               <option value="female">Female</option>  
  34.             </select>  
  35.           </div>  
  36.           <div class="form-group">  
  37.             <label> Address </label>  
  38.             <textarea type="text" />  
  39.           </div>  
  40.           <div>  
  41.             <button class="btn-primary">Submit </button>  
  42.             <button class="btn-secondary">Reset </button>  
  43.           </div>  
  44.         </form>  
  45.       </div>  
  46.       <div class="form-state">  
  47.         <h4>Form State</h4>  
  48.       </div>  
  49.     </div>  
  50.   );  
  51. }  
  1. // style.css  
  2.   
  3. * {  
  4.   font-family: Lato;  
  5. }  
  6.   
  7. .root {  
  8.   padding: 0px 10px;  
  9.   display: grid;  
  10. }  
  11.   
  12. @media screen and (min-width: 800px) {  
  13.   .root {  
  14.     grid-template-columns: 50% 50%;  
  15.   }  
  16. }  
  17.   
  18. .form-group {  
  19.   display: grid;  
  20.   grid-template-columns: 30% 50%;  
  21.   margin: 10px 0px;  
  22. }  
  23.   
  24. input,  
  25. select,  
  26. textarea {  
  27.   padding: 5px;  
  28.   border-radius: 0px;  
  29.   border: 1px solid black;  
  30. }  
  31.   
  32. button {  
  33.   margin-right: 5px;  
  34.   padding: 10px;  
  35.   border: none;  
  36. }  
  37. .btn-primary {  
  38.   background: lightblue;  
  39. }  

Install Formik

 
Install formik in your application with the following command,
  1. npm install --save formik  

Use Formik To Manage Form


We can use formik to manage forms using <Formik /> HOC or useFormik() hook. In this article, we will use the useFormik() hook.
 
Initialize the Form State
  1. export default function App(){  
  2.   
  3.  const formik = useFormik({  
  4.     initialValues: {  
  5.       firstName: '',  
  6.       lastName: '',  
  7.       emailId: '',  
  8.       mobileNumber: undefined,  
  9.       gender: '',  
  10.       address: ''  
  11.     },  
  12.   });  
  13.   
  14.   /* ... form template ... */  
  15. }  
Map the Input Control  
  • Formik uses the name or id property of input control to map it with form state,
  • We need to set the value property of form state 
  • Need to register the formik handleChange handler with onChange event of input control 
  1. <input type="text" name="firstName" value={formik.values.firstName} onChange={formik.handleChange} />  
Here name should be the same as the property initialized in formik state initial values.

We need to set the above properties for all form control as shown below,
  1. // App.js / App.jsx    
  2.     
  3. import React from 'react';    
  4. import './style.css';    
  5. import { useFormik } from 'formik';    
  6.     
  7. export default function App() {    
  8.   const formik = useFormik({    
  9.     initialValues: {    
  10.       firstName: '',    
  11.       lastName: '',    
  12.       emailId: '',    
  13.       mobileNumber: undefined,    
  14.       gender: '',    
  15.       address: ''    
  16.     }    
  17.   });    
  18.     
  19.   return (    
  20.     <div class="root">    
  21.       <div class="form">    
  22.         <h1> Registration </h1>    
  23.         <form>    
  24.           <div class="form-group">    
  25.             <label> First Name </label>    
  26.             <input    
  27.               type="text"    
  28.               name="firstName"    
  29.               value={formik.values.firstName}    
  30.               onChange={formik.handleChange}    
  31.             />    
  32.           </div>    
  33.           <div class="form-group">    
  34.             <label> Last Name </label>    
  35.             <input    
  36.               type="text"    
  37.               name="lastName"    
  38.               value={formik.values.lastName}    
  39.               onChange={formik.handleChange}    
  40.             />    
  41.           </div>    
  42.           <div class="form-group">    
  43.             <label> Email Id </label>    
  44.             <input    
  45.               type="text"    
  46.               name="emailId"    
  47.               value={formik.values.emailId}    
  48.               onChange={formik.handleChange}    
  49.             />    
  50.           </div>    
  51.           <div class="form-group">    
  52.             <label> Mobile Number </label>    
  53.             <input    
  54.               type="text"    
  55.               name="mobileNumber"    
  56.               value={formik.values.mobileNumber}    
  57.               onChange={formik.handleChange}    
  58.             />    
  59.           </div>    
  60.           <div class="form-group">    
  61.             <label> Gender </label>    
  62.             <select    
  63.               name="gender"    
  64.               value={formik.values.gender}    
  65.               onChange={formik.handleChange}    
  66.             >    
  67.               <option value="">Select</option>    
  68.               <option value="male">Male</option>    
  69.               <option value="female">Female</option>    
  70.             </select>    
  71.           </div>    
  72.           <div class="form-group">    
  73.             <label> Address </label>    
  74.             <textarea    
  75.               type="text"    
  76.               name="address"    
  77.               value={formik.values.address}    
  78.               onChange={formik.handleChange}    
  79.             />    
  80.           </div>    
  81.           <div>    
  82.             <button class="btn-primary">Submit </button>    
  83.             <button class="btn-secondary">Reset </button>    
  84.           </div>    
  85.         </form>    
  86.       </div>    
  87.       <div class="form-state">    
  88.         <h4>Form State</h4>    
  89.         <h5>Values:</h5>    
  90.         <code>    
  91.           <pre>{JSON.stringify(formik.values, null, 2)}</pre>    
  92.         </code>    
  93.       </div>    
  94.     </div>    
  95.   );    
  96. }     
Now test your form. As you can see below, we are able to successfully map the form controls.
 
Form Setup with Formik
 
Reduce boilerplate code
 
The above code is perfect, but as you see in the code there is so much boilerplate code, we need to set common props for each form control just the name of the control is different. We can reduce this boilerplate code with the formik helper function getFieldProps(fieldName), which returns the following properties,
  1. {  
  2.    /** Value of the field */  
  3.    value: Value;  
  4.    /** Name of the field */  
  5.    name: string;  
  6.    /** Multiple select? */  
  7.    multiple?: boolean;  
  8.    /** Is the field checked? */  
  9.    checked?: boolean;  
  10.    /** Change event handler */  
  11.    onChange: FormikHandlers['handleChange'];  
  12.    /** Blur event handler */  
  13.    onBlur: FormikHandlers['handleBlur'];  
  14.  }  
We just need to spread these properties in our form control as shown below,
  1. <input type="text" {...formik.getFieldProps('firstName')} />  
As you can see we don't need to write all other properties. Update in the same way on other form controls.
 

Handle Form Submit


Formik provides handleSubmit helper function which we need to register on submit event of the form. Once we will submit the form it will call the onSubmit handler specified at the time of formik initialization with useFormik hook as shown below,
  1. import React from 'react';    
  2. import './style.css';    
  3. import { useFormik } from 'formik';    
  4.     
  5. export default function App() {    
  6.   const formik = useFormik({    
  7.     initialValues: {    
  8.       firstName: '',    
  9.       lastName: '',    
  10.       emailId: '',    
  11.       mobileNumber: undefined,    
  12.       gender: '',    
  13.       address: ''    
  14.     },    
  15.     onSubmit: values => {    
  16.       alert(    
  17.         'Registration Form Submitted \n ' + JSON.stringify(values, null, 2)    
  18.       );    
  19.     }    
  20.   });    
  21.     
  22.   return (    
  23.     <div class="root">    
  24.         <form onSubmit={formik.handleSubmit}>    
  25.           {/* Form Controls */}    
  26.         </form>    
  27.     </div>    
  28.   );    
  29. }     
Reset Form

We can reset the form by using the resetForm() method of formik. We can register it on the onClick event of the reset button.
 
Final Code 
  1. // App.js / App.jsx  
  2.   
  3. import React from 'react';  
  4. import './style.css';  
  5. import { useFormik } from 'formik';  
  6.   
  7. export default function App() {  
  8.   const formik = useFormik({  
  9.     initialValues: {  
  10.       firstName: '',  
  11.       lastName: '',  
  12.       emailId: '',  
  13.       mobileNumber: undefined,  
  14.       gender: '',  
  15.       address: ''  
  16.     },  
  17.     onSubmit: values => {  
  18.       alert(  
  19.         'Registration Form Submitted \n ' + JSON.stringify(values, null, 2)  
  20.       );  
  21.       formik.resetForm();  
  22.     }  
  23.   });  
  24.   
  25.   return (  
  26.     <div class="root">  
  27.       <div class="form">  
  28.         <h1> Registration </h1>  
  29.         <form onSubmit={formik.handleSubmit}>  
  30.           <div class="form-group">  
  31.             <label> First Name </label>  
  32.             <input type="text" {...formik.getFieldProps('firstName')} />  
  33.           </div>  
  34.           <div class="form-group">  
  35.             <label> Last Name </label>  
  36.             <input type="text" {...formik.getFieldProps('lastName')} />  
  37.           </div>  
  38.           <div class="form-group">  
  39.             <label> Email Id </label>  
  40.             <input type="text" {...formik.getFieldProps('emailId')} />  
  41.           </div>  
  42.           <div class="form-group">  
  43.             <label> Mobile Number </label>  
  44.             <input type="text" {...formik.getFieldProps('mobileNumber')} />  
  45.           </div>  
  46.           <div class="form-group">  
  47.             <label> Gender </label>  
  48.             <select {...formik.getFieldProps('gender')}>  
  49.               <option value="">Select</option>  
  50.               <option value="male">Male</option>  
  51.               <option value="female">Female</option>  
  52.             </select>  
  53.           </div>  
  54.           <div class="form-group">  
  55.             <label> Address </label>  
  56.             <textarea type="text" {...formik.getFieldProps('address')} />  
  57.           </div>  
  58.           <div>  
  59.             <button type="submit" class="btn-primary">  
  60.               Submit  
  61.             </button>  
  62.             <button  
  63.               type="reset"  
  64.               class="btn-secondary"  
  65.               onClick={formik.resetForm}  
  66.             >  
  67.               Reset  
  68.             </button>  
  69.           </div>  
  70.         </form>  
  71.       </div>  
  72.       <div class="form-state">  
  73.         <h4>Form State</h4>  
  74.         <h5>Values:</h5>  
  75.         <code>  
  76.           <pre>{JSON.stringify(formik.values, null, 2)}</pre>  
  77.         </code>  
  78.       </div>  
  79.     </div>  
  80.   );  
  81. }  
Final Output
 
 Final Output
 
Check out the Live Application here.

Summary

 
In this article, we have seen how to manage React forms easily with formik. We have seen step-by-step formik setup in react, in the next article, we will see form validation using formik.
   
I hope you like this article, give your valuable feedback and suggestion in the comment section🙂.
 
Next Article:
References