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.