Right now I consider it a question, which can alter to potential proposal.
Although there could be potentially more scenarios, I think this one explains it well. Here is a minimal example: https://codesandbox.io/s/3k0lqyq3qp.
When we leave all fields empty and submit the form all errors coming from yup will be shown. And error which belongs to specific input disappears when onChange is called. Then we write something to both inputs, so they pass validation, and submit the form. Now we get some error from API and set those errors accordingly (line 24). Problem happens when we start editing one input, then validation is run, which returns no errors (they pass yup) and custom errors are overwritten (https://github.com/jaredpalmer/formik/blob/master/src/formik.tsx#L345), which makes overall behaviour inconsistent.
Do you have an idea how to handle this? Would it make sense to merge those errors somehow?
Thanks for your time.
Formik has a status and setStatus which was basically built for this kind of use case. Instead of "merging" errors, just place them on status. Then you can just conditionally display them:
https://codesandbox.io/s/yqj45jwy0v
import React from 'react';
import { render } from 'react-dom';
import { Formik } from 'formik';
import yup from 'yup';
const styles = {
fontFamily: 'sans-serif',
textAlign: 'center',
};
const schema = yup.object().shape({
email: yup.string().required('Email required'),
pswrd: yup.string().required('Password required'),
});
const App = () => (
<div style={styles}>
<Formik
validationSchema={schema}
initialValues={{ email: '', pswrd: '' }}
onSubmit={(values, actions) => {
// setting API errors
actions.setStatus({
email: 'This is email already exists.',
pswrd: 'This is incorrect',
});
}}
render={({ handleSubmit, handleChange, handleBlur, values, errors, status }) => (
<form onSubmit={handleSubmit}>
<input
type="text"
name="email"
value={values['email']}
onChange={handleChange}
onBlur={handleBlur}
/>
<input
type="text"
name="pswrd"
value={values['pswrd']}
onChange={handleChange}
onBlur={handleBlur}
/>
<button type="submit">Submit</button>
{status && status.email ? (
<div>Error: {status.email}</div>
) : (
errors.email && <div>Error: {errors.email}</div>
)}
{status && status.pswrd ? (
<div>Error: {status.pswrd}</div>
) : (
errors.pswrd && <div>Error: {errors.pswrd}</div>
)}
</form>
)}
/>
</div>
);
render(<App />, document.getElementById('root'));
Fun fact:
statuswas initially callederror(singular) andsetErrorin early versions of formik because my idea was to use it for api / top level error responses.
That is exactly what I am looking for! Thank you @jaredpalmer.
Feedback: for some reason, even if I went through the API table of contents and source code couple of times, I couldn't associate it with API errors 馃. Maybe we should add it to the guides section?
Submit a PR?
Will do 馃憤
Most helpful comment
Formik has a
statusandsetStatuswhich was basically built for this kind of use case. Instead of "merging" errors, just place them on status. Then you can just conditionally display them:https://codesandbox.io/s/yqj45jwy0v