HomeBlogWeb DevelopmentBuilding Forms in React with Formik [Examples]

Building Forms in React with Formik [Examples]

Published
24th Apr, 2024
Views
view count loader
Read it in
13 Mins
In this article
    Building Forms in React with Formik [Examples]

    Forms are a crucial way of collecting information from users, which allows us to improve the app's functionality in the future. We'll learn more about Formik and why we need it for our React applications in this article. The software's various features and settings make the development process easier and more controllable. 

    In order to create a form in JavaScript, we will use the most basic html input tag, which mostly comprises of input fields such as text-areas, checkboxes, radio-buttons, select-options, and so on.

    If we want to handle validations, we'll have a difficult time doing so because we'll have to deal with each statement separately on such a large form. So, how can we handle large forms while also performing validations without affecting the user's information? This is when Formik comes to the rescue! 

    What is Formik?

    Formik is a lightweight, free and open-source library for ReactJS or React Native that addresses three primary form creation pain points: 

    • State manipulation 
    • Form Validation (error message) 
    • Form Submission 

    Jared Palmer created the Formik library in response to his frustrations with designing React forms and his desire to standardise the input components and form submission processes. The goal was to keep everything in one place, making testing, refactoring, and reasoning about your forms much easier. 

    Formik's major goal was to build a scalable, high-performing form helper with a simple API that automates the process and leaves the rest to us. 

    Why Should We Use Formik in React?

    React just provides the "view" layer for your app, which means it only givesminimum necessitiesfor creating form components. React components, states, and props are like puzzle pieces that must be put together to create a functional shape. 

    For a form with only two text boxes, it has a lot of code. Consider how many state values you'll need to track in a form with ten or more inputs. 

    Yes, developing forms using React is a pain; and it isrestrictive. The work of building the form and the validation procedures is difficult. At a minimum, you'd need to fill out the following fields on each form: 

    • Set the state for the form's values, errors, and validity. 
    • Taking user input and changing the current state 
    • Validation functions creation 
    • Dealing with submissions 

    Building forms the React manner necessitates writing every step of the process, from state setup through form submission. I've built a lot of React forms, and I always find this aspect of the process complicated and time-consuming. Formik React JS combination is really best for developers. 

    To learn more about React and to know the flow of learning React from start, you can checReact JS syllabus for our courses. 

    Formik Advantages

    • Decreased Latency

    In ReactJS, the purpose of Formik is to create a scalable and performant form helper with a very simple API. Other React form management tools, such as Redux Form, are available. While it is clearly a useful tool that many developers utilise, it does have certain flaws. 

    The employment of reducers is one of Redux Form's drawbacks. A reducer is a function in Redux that takes two arguments: the current state and an action, and returns a new state as a result. For each keystroke in the ReactJS form, the entire top-level reducer is invoked multiple times. 

    Such kind of call to the reducer for each keystroke isn't a factor in smaller applications. Latency, on the other hand, is unavoidable as the program grows in size and will continue to do so. 

    • Extremely Flexible

    Formik is a versatile library that lets you choose when and how much to use it. Yup, for example, may be used with HTML input fields and can be used to construct custom validation criteria. Yup is a value parsing and validation JavaScript schema builder that allows you to construct a schema, change a value to match, validate the shape of an existing value, or both.  

    Prerequisites

    To get started, download and install Formik. This can be accomplished in the following ways: 

    NPM can be used to install Formik using the command npm install formik —save. 

    To install Formic using YARN, type yarn add formik. 

    To use the CDN to install Formik, simply add the following <script> element to the bottom of your HTML code.  

    <script src="https://unpkg.com/formik/dist/formik.umd.product ion.min.js"></script>

    Getting Values in and Out of Form State in Formik

    You don't need to setup state from the function Object() { [native code] } because Formik will set up state internally for saving user inputs through its initialValues prop.

    You can use the <Field /> component instead of the usual HTML input /> component to get values into and out of Formik internal state. You don't need to supply the value and onChange props to the<Field /> component because this component will keep Formik state and input value in sync: 

    <Formik 
      initialValues={{ email: "", password: "" }} 
      onSubmit={({ setSubmitting }) => { 
        alert("Form is validated! Submitting the form"); 
        setSubmitting(false); 
      }} 
    > 
      {() => ( 
        <Form> 
          <div className="form-group"> 
            <label htmlFor="email">Email</label> 
            <Field 
              type="email" 
              name="email" 
              className="form-control" 
            /> 
          </div> 
          <div className="form-group"> 
            <label htmlFor="password">Password</label> 
            <Field 
              type="password" 
              name="password" 
              className="form-control" 
            /> 
          </div> 
        </Form> 
      )} 
    </Formik>

    Using Formik’s handleChange 

    With Formik, there's no need to write your own handleChange method or initialise state in thconstructor. Everything has been taken care of. 

    There is no need to develop your own handleChange method because Formik provides its own handleChange method that you can use to update the state with user inputs. 

    The handleChange function changes the form values based on the name property of the input that has been updated. 

    With input elements, the handleChange method is utilised. The values are updated internally by the Field component without the requirement to implement the handleChange function. 

    Example: 

    const SignupForm = () => { 
      const formik = useFormik({ 
        initialValues: { 
          email: "", 
        }, 
        onSubmit: (values) => { 
          alert(JSON.stringify(values, null, 2)); 
        }, 
      }); 
      return ( 
        <form onSubmit={formik.handleSubmit}> 
          <label htmlFor="email">Email Address</label> 
          <input 
            id="email" 
            name="email" 
            type="email" 
            onChange={formik.handleChange} 
            value={formik.values.email} 
          /> 
          <button type="submit">Submit</button> 
        </form> 
      ); 
    }; 
    

    We have a name input set to email in this case. We've added a onChange event handler to it, as you can see. The handleChange method of the formik object is called by the onChange event handler. 

    This will change the new value in the formik object's values object, allowing us to obtain it from the values object in the onSubmit props. 

    To learn more about React and to know the flow of learning React from start, You can check React JS syllabus Knowledgehut. 

    Validating with Formik

    • At Field Level:

    By writing validation functions and sending them to the Field component's validate prop, we can add field-level validation. 

    Example: 

    import React from "react"; 
    import { Formik, Form, Field } from "formik"; 
    function validateEmail(value) { 
      let error; 
      if (!value) { 
        error = "Required"; 
      } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)) { 
        error = "Invalid email address"; 
      } 
      return error; 
    } 
    export const FormExample = () => ( 
      <div> 
        <h1>Signup</h1> 
        <Formik 
          initialValues={{ 
            email: "" 
          }} 
          onSubmit={(values) => { 
            console.log(values); 
          }} 
        > 
          {({ errors, touched, isValidating }) => ( 
            <Form> 
              <Field name="email" validate={validateEmail} /> 
              {errors.email && touched.email && <div>{errors.email}</div>} 
              <button type="submit">Submit</button> 
            </Form> 
          )} 
        </Formik> 
      </div> 
    ); 
    export default function App() { 
      return ( 
        <div className="App"> 
          <FormExample /> 
        </div> 
      ); 
    } 

    The validateEmail function is created with the value parameter, which contains the input value. After that, we check the value and return validation error messages if it is not correct. In FormExample, we use the Formik and Form components to generate the form. Each field's initial value is stored in initialValues. The name prop in the Field component is set to the same value as in the initialValues. The validation function we defined before is included in validate. The error message can be found under errors. The input's touched state is stored in touched. The isValidating property indicates whether or not the form is being validated. 

    • At Form Level

    Because you have complete access to all of your form's values and props whenever the function executes, form-level validation is handy because you can validate dependent fields simultaneously. 

    In Formik, there are 2 ways to do form-level validation; 

    <Formik validate>andwithFormik({ validate: ... }) 

    <Formik validationSchema>andwithFormik({ validationSchema: ... }) 

    Using validate: 

    Validate is a prop/option in Formik> and withFormik() that accepts either a synchronous or asynchronous function. 

    // Synchronous validation 
     const validate = (values, props /* only available when using withFormik */) => { 
       const errors = {}; 
      
       if (!values.email) { 
         errors.email = 'Required'; 
       } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) { 
         errors.email = 'Invalid email address'; 
       } 
      
       //... 
      
       return errors; 
     }; 
      
     // Async Validation 
     const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); 
      
     const validate = (values, props /* only available when using withFormik */) => { 
       return sleep(2000).then(() => { 
         const errors = {}; 
         if (['admin', 'null', 'god'].includes(values.username)) { 
           errors.username = 'Nice try'; 
         } 
         // ... 
         return errors; 
       }); 
     }; 

    Using validationSchema: 

    For object schema validation, we'll use Yup. It has a similar API to Joi and React Prop Types, but it's little enough for the browser and quick enough for use at runtime. Formik includes a specific config option / prop for Yup object schemas called validationSchema that will automatically translate Yup's validation errors into a lovely object whose keys match values and is touched since we Yup so much. This symmetry makes it simple to manage error message business logic. 

    Add yup to your project using following command: 

    npm install yup –save 
    import React from 'react'; 
     import { Formik, Form, Field } from 'formik'; 
     import * as Yup from 'yup'; 
     const SignupSchema = Yup.object().shape({ 
      firstName: Yup.string() 
         .min(2, 'Too Short!') 
        .max(50, 'Too Long!') 
        .required('Required'), 
       lastName: Yup.string() 
         .min(2, 'Too Short!') 
         .max(50, 'Too Long!') 
         .required('Required'), 
       email: Yup.string().email('Invalid email').required('Required'), 
     }); 
     export const ValidationSchemaExample = () => ( 
       <div> 
         <h1>Signup</h1> 
         <Formik 
           initialValues={{ 
             firstName: '', 
             lastName: '', 
             email: '', 
           }} 
           validationSchema={SignupSchema} 
           onSubmit={values => { 
             // same shape as initial values 
             console.log(values); 
           }} 
         > 
           {({ errors, touched }) => ( 
             <Form> 
               <Field name="firstName" /> 
               {errors.firstName && touched.firstName ? ( 
                 <div>{errors.firstName}</div> 
               ) : null} 
               <Field name="lastName" /> 
               {errors.lastName && touched.lastName ? ( 
                 <div>{errors.lastName}</div> 
               ) : null} 
               <Field name="email" type="email" /> 
               {errors.email && touched.email ? <div>{errors.email}</div> : null} 
               <button type="submit">Submit</button> 
             </Form> 
           )} 
         </Formik> 
       </div> 
     ); 
    • With Manual Triggers:

    With Formik, we can manually initiate validation. 

    For example, we could write: 

    import React from "react"; 
    import { Formik, Form, Field } from "formik"; 
    function validateUsername(value) { 
      let error; 
      if (value === "admin") { 
        error = "Nice try!"; 
      } 
      return error; 
    } 
    export const FormExample = () => ( 
      <div> 
        <h1>Signup</h1> 
        <Formik 
          initialValues={{ 
            username: "", 
          }} 
          onSubmit={(values) => { 
            console.log(values); 
          }} 
        > 
          {({ errors, touched, validateField, validateForm }) => ( 
            <Form> 
              <Field name="username" validate={validateUsername} /> 
              {errors.username && touched.username && <div>{errors.username}</div>} 
              <button type="button" onClick={() => validateField("username")}> 
                Check Username 
              </button> 
              <button 
                type="button" 
                onClick={async () => { 
                  const result = await validateForm(); 
                  console.log(result); 
                }} 
              > 
                Validate All 
              </button> 
              <button type="submit">Submit</button> 
            </Form> 
          )} 
        </Formik> 
      </div> 
    ); 
    export default function App() { 
      return ( 
        <div className="App"> 
          <FormExample /> 
        </div> 
      ); 
    } 

    The validateUsername function checks the username field for validity. The Check Username button in the Form element calls validateField with 'username', which is the Field component's name value. The validateUsername method will be used to match the names. The validateForm method, which provides a promise with any problems identified, can be used to validate all of the fields in the form. So, if we write 'admin' into the input, the promise that is returned is: username: "Nice try!" 

    Form Submission Process in Formik

    If there are any issues, Formik's <Form /> component will immediately run your validation function and cancel the submission process. 

    While a normal <form /> element must include the onSubmit prop, Formik's <Form /> wrapper will run the onSubmit prop function you gave into the <Formik /> component: 

    // Formik's submit code. Won't be executed if there are any errors. 
    onSubmit={({ setSubmitting }) => { 
      alert("Form is validated!"); 
      setSubmitting(false); 
    }} 
    // Vanilla React submit code. Check on validity state then run validation manually. 
    handleSubmit = event => { 
      event.preventDefault(); 
      this.setState({ isSubmitting: true }); 
      const { formValues, formValidity } = this.state; 
      if (Object.values(formValidity).every(Boolean)) { 
        alert("Form is validated!"); 
        this.setState({ isSubmitting: false }); 
      } else { 
        for (let key in formValues) { 
          let target = { 
            name: key, 
            value: formValues[key] 
          }; 
          this.handleValidation(target); 
        } 
        this.setState({ isSubmitting: false }); 
      } 
    }; 

    Formik takesfour lines of code to submit, and you don't have to worry about keeping track of the validity of form inputs. That's really cool! 

    Get up to Speed with Formik

    Formik is one of those open source frameworks that is a must-have if you're developing a React application with a lot of forms.

    By abstracting away portions of your form with components like <Field /> and <Form />, it significantly speeds up your development process and reduces boilerplate code.

    Instead of specifying your own state variables and actions in a vanilla React form, you can simply feed props to the <Formik /> component to perform the same things: handle user inputs, validate inputs, and submit the form. 

    To learn more about React, you can opt for online web development certificate and get certified.

    Frequently Asked Questions (FAQs)

    1Can we use Yup without Formik?

    Yes, it is possible to use Yup without formik. You can use cast() if u want to use yup without formik.  

    2Does Formik cost money?

    No, formik is an open-source form library for react and react native. You are free to install and use Formik for your react or React Native applications.  

    3Is Formik a framework?

    No, Formik is a library for React and React native. You just need to import  formik to use in your applications.  

    4Can we use Formik with Redux?

    Yes, we can use formic with Redux. You need to use dispatch with props and props have to be passed with submit function.  

    5Can Formik be used with React Native?

    Yes, Formik can be used with React Native as Formik is an open-source library for React and React native.  

    Profile

    Sachin Bhatnagar

    Blog Author

    Sachin Bhatnagar is an experienced education professional with 20+ years of expertise in Media & Entertainment and Web Technologies. Currently, as the Program Director - Full-Stack at KnowledgeHut, he excels in curriculum development, hands-on training, and strategic deployment of industry-centric educational programs. His online training programs on have attracted over 25,000 learners since 2014. He actively contributes to the development of full-stack training products, leveraging KnowledgeHut's advanced learning platform. Collaborating with organizational leaders, he ensures the success of these programs and has created several technology programs prominently featured in KnowledgeHut's course offerings.

    Share This Article
    Ready to Master the Skills that Drive Your Career?

    Avail your free 1:1 mentorship session.

    Select
    Your Message (Optional)

    Upcoming Web Development Batches & Dates

    NameDateFeeKnow more
    Course advisor icon
    Course Advisor
    Whatsapp/Chat icon