Categories
React

Make Form Handling Easy in React Apps with Formik — Error Messages and Binding to Arrays and Nested Properties

Spread the love

Formik is a library that makes form handling in React apps easy.

In this article, we’ll look at how to handle form inputs with Formik.

Displaying Error Messages

We can display form validation error messages by rendering the values of the errors object.

For instance, we can write:

import React from "react";
import { Formik, Form, Field } from "formik";
import * as Yup from "yup";

const schema = Yup.object().shape({
  email: Yup.string().email("Invalid email").required("Required")
});

export const FormExample = () => (
  <div>
    <Formik
      initialValues={{
        email: ""
      }}
      validationSchema={schema}
      onSubmit={(values) => {
        console.log(values);
      }}
    >
      {({ errors, touched }) => (
        <Form>
          <Field name="email" />
          {touched.email && errors.email && <div>{errors.email}</div>}
          <button type="submit">Submit</button>
        </Form>
      )}
    </Formik>
  </div>
);
export default function App() {
  return (
    <div className="App">
      <FormExample />
    </div>
  );
}

Then we render the errors.email property to get the value of the email field.

When we type in something that’s not an email address, we’ll see the error message displayed.

Arrays and Nested Objects

Formik works with arrays and nested objects.

For example, we can bind form fields to nested properties by writing:

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

export const FormExample = () => (
  <div>
    <Formik
      initialValues={{
        social: {
          facebook: "",
          twitter: ""
        }
      }}
      onSubmit={(values) => {
        console.log(values);
      }}
    >
      <Form>
        <Field name="social.facebook" />
        <Field name="social.twitter" />
        <button type="submit">Submit</button>
      </Form>
    </Formik>
  </div>
);
export default function App() {
  return (
    <div className="App">
      <FormExample />
    </div>
  );
}

In the initialValues prop, we have the social object with some properties inside.

To bind to those, we just set the name prop of the Field components to the property paths of those properties.

Then values in the onSubmit callback would have those values set.

We can also bind our Field input values to array entries.

To do this, we write:

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

export const FormExample = () => (
  <div>
    <Formik
      initialValues={{
        friends: ["james", "mary"]
      }}
      onSubmit={(values) => {
        console.log(values);
      }}
    >
      <Form>
        <Field name="friends[0]" />
        <Field name="friends[1]" />
        <button type="submit">Submit</button>
      </Form>
    </Formik>
  </div>
);
export default function App() {
  return (
    <div className="App">
      <FormExample />
    </div>
  );
}

We just set the name prop to the path to the array entry we want to bind to.

Also, we can remove nesting by adding properties with dots to separate the path segments.

For instance, we can write;

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

export const FormExample = () => (
  <div>
    <Formik
      initialValues={{
        "owner.name": ""
      }}
      onSubmit={(values) => {
        console.log(values);
      }}
    >
      <Form>
        <Field name="['owner.name']" />
        <button type="submit">Submit</button>
      </Form>
    </Formik>
  </div>
);
export default function App() {
  return (
    <div className="App">
      <FormExample />
    </div>
  );
}

We have the 'owner.name' property in initialValues .

Then we set the name prop to ['owner.name'] to do the binding automatically.

Conclusion

We can display form validation error messages and bind input fields to nested properties and array entries with Formik.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *