'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 |
