final-form / react-final-form

🏁 High performance subscription-based form state management for React
https://final-form.org/react
MIT License
7.38k stars 481 forks source link

Async field & async record level validation #968

Open onosendi opened 2 years ago

onosendi commented 2 years ago

If the record-level validation is async, it waits for async field-level validation. Is there a way around this?

Say there's a validation error on the email field. When I type in the username field, emails error will be undefined until username resolves. This causes all of the shown errors to flicker whenever typing in username.

This comes from using yup for record-level validation, and debouncing a field-level validation.

EDIT: Ah, schema.validateSync fixed the issue, turning record-level into synchronous. Still wondering, though?

function sleep() {
  return new Promise((resolve) => { setTimeout(resolve, 1000); });
}

export default function Foo() {
  return (
    <Form
      validate={async (values) => {
        const errors = {};
        if (!values.email) {
          errors.email = 'Required';
        }
        return errors;
      }}
      render={() => (
        <form>
          <Field
            name="username"
            validate={async () => { await sleep(); }}
            render={({ input, meta }) => (
              <input {...input} />
            )}
          />
          <Field
            name="email"
            render={({ input, meta }) => (
              <>
                <input {...input} />
                {(meta.touch && meta.error) && meta.error}
              </>
            )}
          />
        </form>
      )}
    />
  );
}
bertho-zero commented 2 years ago

Testable here: https://codesandbox.io/s/loving-ramanujan-b954o9?file=/src/App.tsx:935-956