Forms with Formik + TypeScript
Tags: formik, typescript, react
Published: 2019-04-02 14:25:25

---
title: Forms with Formik + TypeScript
published: true
description: One of the most painful topics for React developers always was how to build nice forms and have a nice clean code. Some people might think that it’s not necessary to use a third-party library, but in some cases, that’s needed especially when we need more complex forms
tags: #formik #typescript #react
---

![](https://cdn-images-1.medium.com/max/2560/1*nt8jD9-bjQvWWjMkf-gspw.jpeg)

One of the most painful topics for React developers always was how to build nice forms and have a nice clean code. Some people might think that it’s not necessary to use a third-party library, but in some cases, that’s needed especially when we need more complex forms. First, we started with Redux Form, a lot of people used it for a long time but then we started to ask ourselves if it’s a good idea and the best way to manage our form state using our Redux store. We don’t need to have our form state in our Redux store, it’s such a not good practice at all.

Then, Formik really came to change it for us and let our forms so easy to build and our code so readable and well-written that now we don’t have to worry too much about it. We know that Formik code is written in TypeScript but a lot of people still don’t know how to use it the right way.

So, in this article, we’re going to learn about how to use Formik with TypeScript, since a lot of developers has been startedto use it lately, let’s jump into this hype and see how we can improve more our forms.

### Starting

First, let’s start installing some dependencies:

    yarn add formik yup @types/yup

Now, we’re going to start to build our form importing some things that we’re going to need: we’re going to import the `withFormik` HOC that passes our props and form handlers, and also import the `FormikProps`. We’re going also import yup to validate our fields.

    import { withFormik, FormikProps } from "formik";
    import * as Yup from "yup";

Now, to start to build our forms, we need first define some interfaces. Let’s defined an interface called `FormValues` that’s going to define all the values
that we’re going to have in our form:

    interface FormValues {
        email: string;
        password: string;
    }

We’ll also define other interface called `OtherProps`, that in case we want to
pass other props to our component. In our case, we’re going to pass a property
called `title`:

    interface OtherProps {
        title?: string;
    }

Our last interfaces it’s going to be called `MyFormProps`, and with that interface, we can define some properties for our initial values, in case we want
to have some initial values.

    interface MyFormProps {
        initialEmail?: string;
        initialPassword?: string;
    }

Now, we’re going to write our component called `InnerForm`, pass the interfaces
that we created, and also put some extra code:

    const InnerForm = (props: OtherProps & FormikProps<FormValues>) => {
    const {
        values,
        errors,
        touched,
        handleChange,
        handleBlur,
        handleSubmit,
        isSubmitting,
        title
    } = props;

    return (
        <Wrapper>
            <h1>{title}</h1>
            <form onSubmit={handleSubmit}>
                <InputWrapper>
                    <Label>Email</Label>
                    <Input
                        width={50}
                        type="email"
                        name="email"
                        onChange={handleChange}
                        onBlur={handleBlur}
                        value={values.email}
                    />
                </InputWrapper>

                <InputWrapper>
                    <Label>Password</Label>
                    <Input
                        width={50}
                        type="password"
                        name="password"
                        onChange={handleChange}
                        onBlur={handleBlur}
                        value={values.password}
                    />
                </InputWrapper>

                <button
                    type="submit"
                    disabled={
                        isSubmitting ||
                        !!(errors.email && touched.email) ||
                        !!(errors.password && touched.password)
                    }
                >
                    Sign In
                </button>
            </form>
        </Wrapper>
    );
};

We passed our props with `OtherProps` and we also wrapped our `FormValues` inside the `FormikProps`. The rest of the code it’s pretty self-explained, now we’re going to create our final component wrapped with the `withFormik` HOC.

First, let’s write our component called `App` and pass the `MyFormProps` and `FormValues` inside the withFormik.

    const App = withFormik<MyFormProps, FormValues>({
  ...

Now, inside our wrapped component, inside our `mapPropsToValues` method, if we
want to pass an initial value to one of our fields, we can, or we can just pass
an empty string.

    mapPropsToValues: props => ({
        email: props.initialEmail || "",
        password: props.initialPassword || ""
}),

We’re going to use yup to validate our fields so after the `mapPropsToValues`
method, let’s put the following code:

    validationSchema: Yup.object().shape({
        email: Yup.string()
            .email("Email not valid")
            .required("Email is required"),
        password: Yup.string().required("Password is required")
    }),

Now, let’s write the `handleSubmit` function and also pass the `FormValues` to
validate our props.

    handleSubmit({ email, password }: FormValues, { props, setSubmitting, setErrors }) {
        console.log(email, password);
    }

Pretty simple, now our whole `App` component should look like this:

    const App = withFormik<MyFormProps, FormValues>({
        mapPropsToValues: props => ({
            email: props.initialEmail || "",
            password: props.initialPassword || ""
        }),

        validationSchema: Yup.object().shape({
            email: Yup.string()
            .email("Email not valid")
            .required("Email is required"),
            password: Yup.string().required("Password is required")
        }),

        handleSubmit(
            { email, password }: FormValues,
            { props, setSubmitting, setErrors }
        ) {
            console.log(email, password);
        }
    })(InnerForm);

[You can find all the code from this article
here.](https://codesandbox.io/s/0vx7lk97xp)

## Conclusion

As you can see, Formik is a really helpful lib to let us write better forms and
let our code more readable.

This is a simple example of how to use Formik with TypeScript, but you can improve it and use it the way you want. The goal here is to show how to use it the best way and let our code strongly-typed and safer.