TutorialsCourses
Course Menu
Formik for Beginners

Your first Field

Intro

With a Formik context all setup, as well as a Form we're ready to explore adding inputs so your form can start receiving data. The first method is the Field component. It has 3 different methods of rendering which we'll cover.

Field Default

The most basic method is just supplying a name field. The name field will link up a specific field value to the path you have supplied. So in the case below we want the Field to update the firstName key of our form. The default of Field is treated as just an input with type="text". So you are able to add all the normal styling and other props to a Field and it will be applied.

<Formik
  initialValues={{
    firstName: "",
  }}
  onSubmit={handleSubmit}
>
  {() => {
    return (
      <Form className="h-screen flex content-center flex-col justify-center">
        <Field name="firstName" className="border-2" />
      </Form>
    );
  }}
</Formik>

Field Component

Field also takes a component prop that if you supply a custom component will forward all the internal field props on to that component. In this case we only care about the field prop that Field passes down. This includes things like value="" and onChange and onBlur, etc.

const MySpecialField = ({ field }) => {
  return <input {...field} className="border-2" />;
};

To use the component you pass it in to component prop. The className has been moved into the special field but just note that all props you pass to Field will be passed down as props. However Formik will override the field and form prop as those are internal prop names passed to the component to allow you to control things you need.

<Formik
  initialValues={{
    firstName: "",
  }}
  onSubmit={handleSubmit}
>
  {() => {
    return (
      <Form className="h-screen flex content-center flex-col justify-center">
        <Field name="firstName" component={MySpecialField} />
      </Form>
    );
  }}
</Formik>

Field Child Function

Finally if you don't want to pass props and need access to data that may be supplied in your render. For example if you are loading data, have other state you need to reference, etc. You can supply a child function. The child function will pass the same props as if you supplied a component. The only real requirement for basic input needs is to spread the field prop onto the input.

<Formik
  initialValues={{
    firstName: "",
  }}
  onSubmit={handleSubmit}
>
  {() => {
    return (
      <Form className="h-screen flex content-center flex-col justify-center">
        <Field name="firstName">
          {({ field }) => {
            return <input {...field} className="border-2" />;
          }}
        </Field>
      </Form>
    );
  }}
</Formik>

Wrap Up

Overall pick the version of Field that works best for your use case. In general I find myself mixing these but reaching for the child as a function as it allows me to grab other data that is available without the need to pass significant amount of props. Also in general I may want a Field that has no reference to Formik but merely want to pass along onChange, onBlur, and other small bits of info.

All together all the Fields in conjunction look like this. They will all update, and all render exactly the same.

import React from "react";
import { Formik, Form, Field } from "formik";

const MySpecialField = ({ field }) => {
  return <input {...field} className="border-2" />;
};

function App() {
  const handleSubmit = (values) => {
    console.log(values);
  };

  return (
    <div className="App">
      <Formik
        initialValues={{
          firstName: "",
        }}
        onSubmit={handleSubmit}
      >
        {() => {
          return (
            <Form className="h-screen flex content-center flex-col justify-center">
              <div className="space-x-4 flex content-center justify-center">
                <Field name="firstName" className="border-2" />
                <Field name="firstName" component={MySpecialField} />
                <Field name="firstName">
                  {({ field }) => {
                    return <input {...field} className="border-2" />;
                  }}
                </Field>
                <button
                  type="submit"
                  className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
                >
                  Submit
                </button>
              </div>
            </Form>
          );
        }}
      </Formik>
    </div>
  );
}

export default App;