Versions:
formik: 2.2.6
yup: 0.32.8
I've been having this issue with formik today so I set about creating a minimally reproducible example.
In the example you'll see that we have different validators attached to the data field including: required, length(6) and an async test.
When the correct conditions are met for an error message to show, you'll notice that the wrong error message is shown until the async test resolves. You'll also notice that between the wrong message showing, and the async test resolving, formik.isValidating is false.
What are we doing wrong here and how can we prevent this incorrect error message from showing up?
Additionally, how can we get formik.isValidating to return true when the async test is yet to resolve? If we could do that we could indicate to the user that validation is still pending.
Minimal Reproducible Code: https://codesandbox.io/s/black-shape-z5e54?file=/src/App.js
import React, { useEffect, useRef } from "react";
import "./styles.css";
import { useFormik } from "formik";
import * as yup from "yup";
const asyncTest = (value, context) => {
return new Promise((res) => {
setTimeout(() => {
res(context.createError({ message: "This ain't right" }));
}, 3000);
});
};
const validationSchema = yup.object().shape({
data: yup
.string()
.required("Data is required")
.length(6)
.test("async-val", "", asyncTest)
});
export default function App() {
const formik = useFormik({
validationSchema,
initialValues: {
data: ""
}
});
// A helper to simulate a field that auto blurs
// when completing. In the real code, handleBlur is called
// when the pin input reaches its sixth character.
const inputRef = useRef(null);
useEffect(() => {
if (formik.values.data.length >= 6) {
inputRef.current.blur();
}
}, [formik.values.data]);
return (
<>
<input
type="text"
name="data"
ref={inputRef}
value={formik.values.data}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
{formik.errors.data && formik.touched.data && (
<div>{formik.errors.data}</div>
)}
</>
);
}