'Replace Yup with custom function for basic validation

On this StackBlitz: https://stackblitz.com/edit/react-formik-yup-example-uhdg-uf8bl1?file=App.js

I have the following very simple code:

import React from 'react';
import { Formik } from 'formik';
import * as Yup from 'yup';
import Form from './Form';
import toastr from 'toastr';

const fullNameValidation = (fullName) => {
  var regexp = /^[a-z]{3,} [a-z]{3,}$/i
  const valid = regexp.test(fullName);
  return valid ? {
    isValid: true,
  } : {
    isValid: false,
    errorMessage: 'The Full Name should include a First and Last Name with at least 3 chars minimum each.',
  }
}

const getValidationSchema = () => {
  const schemaObject = {};
  schemaObject['fullName'] =
    Yup.string()
    .test('validator-custom-name', function (value) {
      const validation = fullNameValidation(value);
      if (!validation.isValid) {
        return this.createError({
          path: this.path,
          message: validation.errorMessage,
        });
      }
      else {
        return true;
      }
    });
  return Yup.object().shape(schemaObject);
};

export default () => {
  return (
    <Formik
      initialValues={{
        fullName: '',
      }}
      validationSchema={ getValidationSchema() }
      onSubmit={(values, { resetForm }) => {
        toastr.options = {
          hideDuration: 300,
          timeOut: 60000,
        };
        toastr.success('Success! Data submitted.');
        resetForm();
      }}
    >
      {(props) => <Form {...props} />}
    </Formik>
  );
};

where you can see I basically use it to get the validation schema I will pass to Formik. That validation schema just use the .test(...) function with a custom validation function I pass into it.

My question is: is there any way to get rid of Yup library and implement that logic by myself? That way I will save on the final bundle: 59.3 KB (gzipped: 18.9 KB).

Thanks!



Solution 1:[1]

You can use validate attribute in Formik. You can check it out here

Here is the change

<Formik
      initialValues={{
        fullName: '',
      }}
      validate={(values) => {
        const errors = {};

        const validation = fullNameValidation(values.fullName);
        if (!validation.isValid) {
          errors.fullName = validation.errorMessage;
        }

        return errors;
      }}
      onSubmit={(values, { resetForm }) => {
        toastr.options = {
          hideDuration: 300,
          timeOut: 60000,
        };
        toastr.success('Success! Data submitted.');
        resetForm();
      }}
>
      {(props) => <Form {...props} />}
</Formik>

You also can use that validate under field level. For example

import React from 'react';
import { Field, Form, ErrorMessage } from 'formik';

const fullNameValidation = (fullName) => {
  var regexp = /^[a-z]{3,} [a-z]{3,}$/i;
  const valid = regexp.test(fullName);
  return valid
    ? {
        isValid: true,
      }
    : {
        isValid: false,
        errorMessage:
          'The Full Name should include a First and Last Name with at least 3 chars minimum each.',
      };
};

const validateFullName = (value) => {
  const validation = fullNameValidation(value);
  return !validation.isValid ? validation.errorMessage : null;
};

export default ({ errors, touched, isSubmitting }) => {
  return (
    <Form>
      <div className="form-group">
        <label htmlFor="fullName">Full Name</label>
        <Field
          name="fullName"
          type="text"
          className={
            'form-control' +
            (errors.fullName && touched.fullName ? ' is-invalid' : '')
          }
          validate={validateFullName}
        />
        <ErrorMessage
          name="fullName"
          component="div"
          className="invalid-feedback"
        />
      </div>
      <div className="form-group">
        <button
          type="submit"
          className="btn btn-primary mr-2"
          disabled={isSubmitting}
        >
          Submit
        </button>
      </div>
    </Form>
  );
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1