Может ли поле в реагирующей окончательной форме пометить себя как недействительное / запретить отправку? - PullRequest
0 голосов
/ 10 января 2020

У меня есть настраиваемое поле для загрузки файлов, которое загружает файлы сразу после их выбора / удаления и возвращает UUID для последующей отправки. Итак, в основном то, что в настоящее время делает большинство веб-приложений (например, Facebook, Twitter и т. Д. c.), Когда вы удаляете файл.

Это все достаточно просто для обработки с помощью final-form - мое поле просто вызывает final- Функция onChange формы после завершения загрузки передает UUID в окончательную форму.

Однако, если пользователь отправляет форму во время загрузки , он отправит форму без UUID файла, поскольку с точки зрения окончательной формы файл еще не выбран. Особенно для больших файлов это будет проблематично c, поскольку пользователи могут не осознавать, что им все еще нужно ждать (даже с индикатором загрузки). Пометить поле как обязательное также не вариант, так как недопустимо предоставление файла вообще (или поле может разрешить несколько файлов, или вы заменяете ранее загруженный файл) - так что единственный случай, когда поле «недопустимо» "это когда файл в данный момент загружается.

Вот кодекс-бокс с небольшим фиктивным приложением, которое должно обеспечить хорошую отправную точку при любой попытке его решить: https://codesandbox.io/s/polished-fast-k80t7

Идея состоит в том, что поле становится недействительным при нажатии «Притворяться, чтобы начать загрузку» и снова становится действительным после нажатия «Притвориться к окончанию sh загрузки».

Обратите внимание, что я ищу Чистый способ сделать это, сохраняя при этом разные вещи, т.е. я бы предпочел не добавлять состояние для этого в компонент, содержащий Form - также потому, что функции валидации должны быть идемпотентными, поэтому проверка внешнего состояния там будет в значительной степени нарушена (как показывает моя попытка сделать это ).


Если ссылки на коды и ящики когда-либо прекратятся, h Вот соответствующий код из первой ссылки (так как другая в любом случае просто неудачная попытка):

<code>import React, { useState } from "react";
import { render } from "react-dom";
import Styles from "./Styles";
import { Form, Field } from "react-final-form";

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

const onSubmit = async values => {
  await sleep(300);
  window.alert(JSON.stringify(values, 0, 2));
};

const MyFileUploader = ({ input: { value, onChange }, meta: { invalid } }) => {
  const [isUploading, setUploading] = useState(false);
  const handleStartClick = () => {
    setUploading(true);
  };
  const handleFinishClick = () => {
    setUploading(false);
    onChange("0xdeadbeef"); // let's pretend this is the file UUID ;)
  };
  const style = { color: invalid ? "#f00" : "#000" };
  if (value) {
    return <em style={style}>{value}</em>;
  } else if (isUploading) {
    return (
      <button type="button" onClick={handleFinishClick} style={style}>
        Pretend to finish uploading
      </button>
    );
  } else {
    return (
      <button type="button" onClick={handleStartClick} style={style}>
        Pretend to start uploading
      </button>
    );
  }
};

const App = () => (
  <Styles>
    <h1>React Final Form</h1>
    <Form
      onSubmit={onSubmit}
      initialValues={{ file: null }}
      render={({ handleSubmit, form, submitting, values }) => (
        <form onSubmit={handleSubmit}>
          <div>
            <label>File</label>
            <Field name="file" component={MyFileUploader} />
          </div>
          <div className="buttons">
            <button type="submit" disabled={submitting}>
              Submit
            </button>
            <button type="button" onClick={form.reset} disabled={submitting}>
              Reset
            </button>
          </div>
          <pre>{JSON.stringify(values, 0, 2)}
)} /> ); визуализации ( , document.getElementById ("root"));

1 Ответ

1 голос
/ 10 января 2020

Интересный вопрос.

Как насчет этого? Когда файл загружается, он отображает поле, которое всегда будет недействительным, блокируя таким образом отправку.

const SubmitBlocker = ({ children }) => (
  <Field name="uploading" validate={() => children}>
    {({ meta: { touched, error } }) =>
      meta.touched && meta.error ? meta.error : null
    }
  </Field>
);

Edit beautiful-monad-84nu0

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...