En este StackBlitz: https://stackblitz.com/edit/react-formik-yup-example-uhdg-uf8bl1?file=App.js
Tengo el siguiente código muy simple:
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 = /^[az]{3,} [az]{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> ); }; donde puede ver que básicamente lo uso para obtener el esquema de validación que pasaré a Formik . Ese esquema de validación solo usa la .test(...) con una función de validación personalizada que le paso.
Mi pregunta es: ¿hay alguna forma de deshacerme de la biblioteca Yup e implementar esa lógica por mí mismo? De esa manera ahorraré en el paquete final: 59,3 KB (comprimido con gzip: 18,9 KB).
¡Gracias!
Puede usar el atributo de validate en Formik . Puedes comprobarlo aquí
Aquí está el cambio
<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> También puede usar esa validate en el nivel de campo. Por ejemplo
import React from 'react'; import { Field, Form, ErrorMessage } from 'formik'; const fullNameValidation = (fullName) => { var regexp = /^[az]{3,} [az]{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> ); };