Formik has first class support for yup
. It's a declarative way to handle both synchronous and asynchronous error handling. It has methods that allow you to transform, and do custom error checking when necessary.
To use yup
you can import it piece by piece. Our Formik
values are in the shape of an object
. So we import the object
validation from yup
. Also we will be validating just strings
so we'll import the string
validator as well.
To put it together we first declare we want to check a shape.
object().shape({});
Then it excepts that we describe the shape of our data using the keys that map to the keys on our values
. In our case we want to check our firstName
isn't empty.
Inside of our shape
we give it our object, and specify that firstName
is a string()
and that it is required()
. The value you pass to the required()
call will be the message when this validation fails. In our case the message is Required
.
{ firstName: string().required("Required"), }
import { object, string } from "yup"; const NameValidation = object().shape({ firstName: string().required("Required"), });
Formik has first class support, so rather than calling validate
function we provide a validationSchema
. Formik internals know that it's a yup
schema. It doesn't matter if you have sync or async validations in Yup it'll still work.
Formik knows how to map the errors returned from yup
to the appropriate structure for it's own internal error
system.
<Formik initialValues={{ firstName: "", }} onSubmit={handleSubmit} validationSchema={NameValidation} />
import React from "react"; import { Formik, Form, Field, useField, ErrorMessage } from "formik"; import { object, string } from "yup"; const NameValidation = object().shape({ firstName: string().required("Required"), }); const MySpecialField = () => { const [field, meta] = useField("firstName"); return ( <div> <input {...field} className="border-2" /> {meta.touched && meta.error && <div>{meta.error}</div>} </div> ); }; function App() { const handleSubmit = (values) => { console.log(values); }; return ( <div className="App"> <Formik initialValues={{ firstName: "", }} onSubmit={handleSubmit} validationSchema={NameValidation} > {() => { return ( <Form className="h-screen flex content-center flex-col justify-center"> <div className="space-x-4 flex content-center justify-center"> <div> <Field name="firstName" className="border-2" /> <ErrorMessage name="firstName" component="div" /> </div> <MySpecialField /> <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;