Асинхронная проверка полей массива форм

Я пытаюсь реализовать асинхронную проверку react-final-form-array, Но его возвращение обещание, но не показывает ошибку на всех.

Я взял ссылку на этот код для проверки asnyc и создал свою собственную версию с окончательным массивом форм здесь.

Форма:

<Form
  onSubmit={onSubmit}
  mutators={{
    ...arrayMutators
  }}
  initialValues={{ customers: [{ placeholder: null }] }}
  validate={formValidate}
  render={({
    handleSubmit,
    mutators: { push, pop }, // injected from final-form-arrays above
    pristine,
    reset,
    submitting,
    values,
    errors
  }) => {
    return (
      <form onSubmit={handleSubmit}>
        <div>
          <label>Company</label>
          <Field name="company" component="input" />
        </div>
        <div className="buttons">
          <button type="button" onClick={() => push("customers", {})}>
            Add Customer
          </button>
          <button type="button" onClick={() => pop("customers")}>
            Remove Customer
          </button>
        </div>
        <FieldArray name="customers" validate={nameValidate}>
          {({ fields }) =>
            fields.map((name, index) => (
              <div key={name}>
                <label>Cust. #{index + 1}</label>
                <Field
                  name={`${name}.firstName`}
                  component={testInput}
                  placeholder="First Name"
                />
                <Field
                  name={`${name}.lastName`}
                  component={testInput}
                  placeholder="Last Name"
                />
                <span
                  onClick={() => fields.remove(index)}
                  style={{ cursor: "pointer" }}
                >
                  ❌
                </span>
              </div>
            ))
          }
        </FieldArray>

        <div className="buttons">
          <button type="submit" disabled={submitting || pristine}>
            Submit
          </button>
          <button
            type="button"
            onClick={reset}
            disabled={submitting || pristine}
          >
            Reset
          </button>
        </div>
        <pre>
          nameValidate Function:{"\n"}
          {JSON.stringify(nameValidate(values.customers), 0, 2)}
        </pre>
        <pre>
          Form errors:{"\n"}
          {JSON.stringify(errors, 0, 2)}
        </pre>
        <pre>
          Form values:{"\n"}
          {JSON.stringify(values, 0, 2)}
        </pre>
      </form>
    );
  }}
/>

Проверить функцию:

const duplicateName = async value => {
  await sleep(400);
  if (
    ~["john", "paul", "george", "ringo"].indexOf(value && value.toLowerCase())
  ) {
    return { firstName: "name taken!" };
  }
};

const nameValidate = values => {
  if (!values.length) return;

  const errorsArray = [];

  values.forEach(value => {
    if (value) {
      let errors = {};

      if (!value.firstName) errors.firstName = "First Name Required";
      if (Object.keys(errors).length === 0) {
        errors = duplicateName(value.firstName);
        console.log("errors", errors);
      }
      errorsArray.push(errors);
    }
  });

  return errorsArray;
};

1 ответ

Решение

Хорошо, вы смешиваете проверку таким образом, что это не разрешено. Вы не можете встроить Promise в массив ошибок, вся функция проверки должна возвращать обещание. Вот исправленная версия. await duplicateName() это важный бит.

const nameValidate = async values => {
  if (!values.length) return

  return await Promise.all(
    values.map(async value => {
      let errors = {}
      if (value) {
        if (!value.firstName) errors.firstName = 'First Name Required'
        if (Object.keys(errors).length === 0) {
          errors = await duplicateName(value.firstName)
        }
      }
      console.error(errors)
      return errors
    })
  )
}
Другие вопросы по тегам