Written by: Geoffrey Callaghan

yup tutorial

Yup Tutorial

Yup is a JavaScript schema builder for value parsing and validation. It is often used in combination with form libraries like Formik or React Hook Form to handle form validation. This tutorial will walk you through the basics of using Yup for schema validation.

Step 1: Install Yup

You can install Yup using npm or yarn:

npm install yup
# or
yarn add yup

Step 2: Basic Usage of Yup

To get started with Yup, let’s create a simple validation schema for an object with a name and an email.

  1. Create a basic validation schema:
import * as Yup from 'yup';

const schema = Yup.object().shape({
  name: Yup.string()
    .required('Name is required')
    .max(15, 'Name must be 15 characters or less'),
  email: Yup.string()
    .email('Invalid email address')
    .required('Email is required')
});
  1. Validate data using the schema:
const data = {
  name: 'John Doe',
  email: 'johndoe@example.com'
};

schema
  .validate(data)
  .then(valid => {
    console.log('Validation succeeded:', valid);
  })
  .catch(err => {
    console.log('Validation failed:', err.errors);
  });

Step 3: Integrating Yup with a Form Library

Using Yup with Formik

Formik is a popular form library that integrates well with Yup for validation.

  1. Install Formik:
npm install formik
# or
yarn add formik
  1. Create a form component using Formik and Yup:
import React from 'react';
import { Formik, Field, Form, ErrorMessage } from 'formik';
import * as Yup from 'yup';

const SignupForm = () => {
  const validationSchema = Yup.object().shape({
    name: Yup.string()
      .required('Name is required')
      .max(15, 'Name must be 15 characters or less'),
    email: Yup.string()
      .email('Invalid email address')
      .required('Email is required')
  });

  return (
    <Formik
      initialValues={{ name: '', email: '' }}
      validationSchema={validationSchema}
      onSubmit={(values, { setSubmitting }) => {
        setTimeout(() => {
          alert(JSON.stringify(values, null, 2));
          setSubmitting(false);
        }, 400);
      }}
    >
      <Form>
        <div>
          <label htmlFor="name">Name</label>
          <Field name="name" type="text" />
          <ErrorMessage name="name" />
        </div>
        <div>
          <label htmlFor="email">Email</label>
          <Field name="email" type="email" />
          <ErrorMessage name="email" />
        </div>
        <button type="submit">Submit</button>
      </Form>
    </Formik>
  );
};

export default SignupForm;

Using Yup with React Hook Form

React Hook Form is another popular library for handling forms in React.

  1. Install React Hook Form:
npm install react-hook-form
# or
yarn add react-hook-form
  1. Install the resolver to use Yup with React Hook Form:
npm install @hookform/resolvers yup
# or
yarn add @hookform/resolvers yup
  1. Create a form component using React Hook Form and Yup:
import React from 'react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as Yup from 'yup';

const SignupForm = () => {
  const validationSchema = Yup.object().shape({
    name: Yup.string()
      .required('Name is required')
      .max(15, 'Name must be 15 characters or less'),
    email: Yup.string()
      .email('Invalid email address')
      .required('Email is required')
  });

  const { register, handleSubmit, formState: { errors } } = useForm({
    resolver: yupResolver(validationSchema)
  });

  const onSubmit = data => {
    alert(JSON.stringify(data, null, 2));
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div>
        <label htmlFor="name">Name</label>
        <input id="name" {...register('name')} />
        {errors.name && <p>{errors.name.message}</p>}
      </div>
      <div>
        <label htmlFor="email">Email</label>
        <input id="email" {...register('email')} />
        {errors.email && <p>{errors.email.message}</p>}
      </div>
      <button type="submit">Submit</button>
    </form>
  );
};

export default SignupForm;

Step 4: Advanced Validation with Yup

Yup can handle more complex validation scenarios, such as conditional validation, nested objects, arrays, and custom validation methods.

Nested Objects

const schema = Yup.object().shape({
  user: Yup.object().shape({
    name: Yup.string().required('Name is required'),
    email: Yup.string().email('Invalid email address').required('Email is required')
  })
});

const data = {
  user: {
    name: 'John Doe',
    email: 'johndoe@example.com'
  }
};

schema.validate(data).then(console.log).catch(console.error);

Arrays

const schema = Yup.object().shape({
  friends: Yup.array().of(
    Yup.object().shape({
      name: Yup.string().required('Name is required'),
      email: Yup.string().email('Invalid email address').required('Email is required')
    })
  )
});

const data = {
  friends: [
    { name: 'Jane Doe', email: 'janedoe@example.com' },
    { name: 'John Smith', email: 'johnsmith@example.com' }
  ]
};

schema.validate(data).then(console.log).catch(console.error);

Conditional Validation

const schema = Yup.object().shape({
  isRequired: Yup.boolean(),
  value: Yup.string().when('isRequired', {
    is: true,
    then: Yup.string().required('Value is required'),
    otherwise: Yup.string()
  })
});

const data = { isRequired: true, value: '' };

schema.validate(data).then(console.log).catch(console.error);

Custom Validation

const schema = Yup.object().shape({
  username: Yup.string().test(
    'is-not-admin',
    'Username cannot be "admin"',
    value => value !== 'admin'
  )
});

const data = { username: 'admin' };

schema.validate(data).then(console.log).catch(console.error);

Conclusion

Yup is a versatile and powerful library for schema validation in JavaScript. It integrates seamlessly with form libraries like Formik and React Hook Form, making it a great choice for form validation in React applications. This tutorial covers the basics, but Yup offers a lot more functionality that you can explore in its official documentation.