Skip to content

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Validating React-Bootstrap Forms with Formik

Nov 27, 2019 • 8 Minute Read

Validating React-Bootstrap Forms with Formik

Creating forms in React can be more complicated than it sounds. You need to both manage the state of your form and validate each field. You may also need to validate the entire form before submission. You may need to keep track of the touched inputs, or if anything in the form has changed. Luckily, in today's age of open source projects and thanks to all of the contributors to React libraries, creating forms isn't all that difficult anymore. I'm going to show you how to use the [Formik] (https://jaredpalmer.com/formik/) library to create forms in React.

Introduction to Formik

Formik is a forms library created by Jared Palmer, who was motivated to make using forms in React less manual.

My goal with Formik was to create a scalable, performant form helper with a minimal API that does the really, really annoying stuff, and leaves the rest up to you. – Jared Palmer

With Formik, you are able to set up an initial form state, validate at the form level, validate at the field level, and render whatever form elements you need.

We'll be using the react-bootstrap component library throughout this guide. React-Bootstrap has a set of input components that use the classic bootstrap v4 styling. Since bootstrap comes with hundreds of classes and customizable components, using bootstrap could save you a ton of time with writing styles for your form.

Setting up a Formik form

To get started with Formik, we'll need to add it to our project:

      yarn add formik
#or 
npm i --save formik
    

Let's get started with a new form:

      import React from 'react';
import {Formik} from 'formik';

const BookForm = () => {
    return (
        <Formik 
            initialValues={{
                firstName: '',
                lastName: '',
            }}
            onSubmit={() => console.log('form submitted!!')}
            render={(formProps) => (...)}
        />
    )
}
    

This example shows a basic form with three required properties:

  • initialValues
  • onSubmit method
  • render method

InitialValues

The initialValues property represents the starting values of all available fields that will be in your form. For example, if you want to give users the chance to continue a form they started at a previous time, you can populate initialValues with that saved data.

      <Formik 
    initialValues={{
        firstName: 'Marques',
        lastName: 'Woodson',
    }}
    ...
/>
    

onSubmit method

As the name implies, onSubmit is the function that you want to be called when the form is submitted. The arguments provided are (vales, formikBag). Values is an object with the values of all of the form's fields. The formikBag is an object that holds all of the form's injected props and methods, like isValid, setFieldValue, and many other form methods.

      <Formik 
    initialValues={{
        firstName: 'Marques',
        lastName: 'Woodson',
    }}
    onSubmit={(values) => {
        if (values.firstName && values.lastName) {
            console.log('form submission complete!!');
        }
    }}
/>
    

render method

The render method is where you render the actual form. The render function provides a form props parameter that holds the values, errors, handleChange method, handleSubmit method, and handleBlur method.

      <Formik 
    initialValues={{
        firstName: 'Marques',
        lastName: 'Woodson',
    }}
    onSubmit={(values) => {
        if (values.firstName && values.lastName) {
            console.log('form submission complete!!');
        }
    }}
    render={({handleChange, handleSubmit, handleBlur, values, errors}) => (
        <form>
            <input onChange={handleChange} onBlur={handleBlur} value={values.firstName} ... />
            <button onClick={handleSubmit}>Submit</button>
        </form>
    )}
/>
    

Rendering React-Bootstrap Input in a Field

Now that you see how the render function works in Formik, you may be able to guess how we can use react-bootstrap fields in our form. Formik provides a Field component that is used for rendering and connecting inputs to the Formik form. We'll use this component to render our react-bootstrap inputs.

Field

Each Field component needs a name property that should match with a key from the form's values. That is how the form keeps its state in sync with the field values. Formik lets you render custom components to be used within the Field. This is done with one of two available properties on a Field: component or render. We'll also use the render property to render the react-bootstrap input. The arguments of the render function are the field object and a formProps object. The field object contains onChange method, onBlur method, name, and value of the field. The formProps object has the form's state and all of its helper methods.

      import FormControl from 'react-bootstrap/FormControl';
import FormGroup from 'react-bootstrap/FormGroup';
import FormLabel from 'react-bootstrap/FormLabel'; 
<Formik 
    ...
    render={({handleChange, handleSubmit, handleBlur, values, errors}) => (
        <Form>
            <Field 
                name="firstName"
                render={({field, formProps}) => (
                    <FormGroup controlId="firstName">
                        <FormLabel>First Name</FormLabel>
                        <FormControl type={'text'} value={field.value} onChange={field.onChange} />
                    </FormGroup>
                )}
            />
        </Form>
    )}
/>
    

In react-bootstrap, a FormControl is essentially a styled input field. We then wrap the label and FormControl within a FormGroup component, which will add some spacing and styling, as well as wiring up the label with the input using the controlId property.

Perform Input Validation with Formik (onBlur or onChange)

To validate our form, we will use Formik's validate property. This property takes a function with the argument values, which is an object with the form's values. The validate function should return an errors object.

      <Formik 
    ...
    validate={(values) => {
        let errors = {};
        if (!values.firstName) {
            errors.firstName = 'First name is required';
        }

        if (!values.lastName) {
            errors.lastName = 'Last name is required';
        }

        return errors;
    }}
    render={({handleChange, handleSubmit, handleBlur, values, errors}) => (
        ...
    )}
/>
    

Calling the validate() Function Programmatically

You can validate your form programmatically with one of the available methods on the formProps object: validateForm. You can call this function at any time without actually submitting your form.

      <Formik 
    ...
    validate={(values) => {
        let errors = {};
        if (!values.firstName) {
            errors.firstName = 'First name is required';
        }

        if (!values.lastName) {
            errors.lastName = 'Last name is required';
        }

        return errors;
    }}
    render={({handleChange, handleSubmit, handleBlur, values, errors, validateForm}) => (
        <Form>
            <Field 
                name="firstName"
                render={({field, formProps}) => (
                    <FormGroup controlId="firstName">
                        <FormLabel>First Name</FormLabel>
                        <FormControl type={'text'} value={field.value} onChange={field.onChange} />
                    </FormGroup>
                )}
            />
            <button onClick={validateForm}>Validate Form</button>
        </Form>
    )}
/>
    

Conclusion

This guide gave you a brief introduction to the Formik library. You now know how to create a form with Formik using the React-Bootstrap component library. You also know how to run form validation against your form using Formik. There are many other features available in Formik and I highly recommend you check them out in the [documentation] (https://jaredpalmer.com/formik/docs/overview), particularly [Yup-schema form-validation] (https://jaredpalmer.com/formik/docs/guides/validation#flavors-of-validation).

Thanks for reading.

Marques Woodson

Marques W.

Marques has been involved with software development for years, specializing in Javascript application architecture, hybrid mobile application development, and Node.js applications. As a family man living in Chicago, he's had the chance to work with large enterprises doing legacy code optimization and refactoring, and startups building from the ground up. I'm passionate about experimenting with Javascript frameworks and libraries and figuring out what would work best for my current team/project. He also really enjoys teaching and mentoring new developers.

More about this author