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;