Issue
I generated Field in CustomField
and call it in the CustomForm
component. I want to validate each Customefield
in itself with validateAsync
but validateAsync
is not working and meta. the error
object is always empty.
this is my CustomForm
component:
import { Field, Form, Formik, yupToFormErrors } from "formik";
import React, { Component } from "react";
import CustomField from "./customeField";
import * as Yup from "yup";
class CustomForm extends Component {
state = {};
render() {
return (
<Formik
initialValues={{ name1: "", name2: "" }}
onSubmit={(values) => {
console.log(values);
}}
>
<Form>
<CustomField name="name1" lable="name1"></CustomField>
<CustomField name="name2" lable="name2"></CustomField>
<button type="submit">send</button>
</Form>
</Formik>
);
}
}
export default CustomForm;
and this is my CustomField
component
import React, { Component } from "react";
import { Field, Form, Formik, useField, ErrorMessage } from "formik";
import * as Yup from "yup";
const CustomField = ({ lable, ...props }) => {
const [field, meta] = useField(props);
const validateAsync = () =>
Yup.object({
name1: Yup.string().required("error"),
});
return (
<div>
<label htmlFor={props.id || props.name}>{lable}</label>
<Field validate={validateAsync} {...field} {...props} />
{meta.touched && meta.error ? (
<div className="error">{meta.error}</div>
) : (
<div className="error"></div>
)}
</div>
);
};
export default CustomField;
Solution
there are two problems in your code, the first one is how you use the Yup
for validation and the second problem is about that validateAsync
function, as Formik doc mentions you have to get input value from the first argument and as result, you can return undefined (which means there is no error) or a string (error message), BTW it's also possible to return a promise that indicates is input value valid or not.
here is how you can go with this case:
const CustomField = ({ label, name }: CustomFieldProps) => {
const [field, meta] = useField({ name });
const validate = (x: string) => {
const error_msg = "Error!!!";
try {
Yup.string().required(error_msg).validateSync(x).toString();
} catch (error) {
return error_msg;
}
};
return (
<div>
<Field validate={validate} {...field} />
{meta.touched && meta.error && <div className="error">{meta.error}</div>}
</div>
);
};
p.s: here is the link of a working sample sandbox if you need a playground:
https://codesandbox.io/s/formik-field-validate-rx3snh?file=/src/App.tsx:173-650
Answered By - PS-PARSA
Answer Checked By - - Pedro (ReactFix Volunteer)