0

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!

1 Answer 1

0

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>
  );
};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.