У меня есть настраиваемое поле для загрузки файлов, которое загружает файлы сразу после их выбора / удаления и возвращает 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"));