пользовательская форма создания в react-admin, заполненная пользовательскими динамическими данными

#react-admin #react-dropzone

Вопрос:

В react-admin мне нужно изменить форму создания на собственную, очень индивидуальную, логику. Мое приложение получает набор локальных файлов (react-dropzone), считывает метаданные из файлов (пакет exifr) и для каждого из них делает .

Существует проблема с обновлением var FormData и повторным отображением формы. Когда я нажимаю на кнопку выбора некоторых файлов (после обновления страницы):

  • первый раз: данные формы пусты
  • второй раз: в FormData появились новые правильные данные, но форма пуста
  • третий раз: в FormData появились новые правильные данные, форма заполнена правильно

Что странно, что удаление файлов (а не сбор) приводит к:

  • первый раз: FormData содержит новые правильные данные, но форма пуста
  • второй раз: данные формы содержат новые правильные данные, форма заполнена правильно

Отправка данных через поставщика данных не связана с проблемой.

 import React, { useEffect, useState } from 'react';
import { ArrayInput, Create, SimpleFormIterator, DateInput, TextInput, FileInput, SimpleForm } from 'react-admin';
import { useDropzone } from 'react-dropzone';
import exifr from 'exifr';

export const StorageFilesCreate = (props) => {
  const [formData, setFormData] = useState({ files: [] });
  const [files, setFiles] = useState([]);

  const AddDropZone = () => {
    const { getRootProps, getInputProps, open } = useDropzone({
      accept: 'image/*',
      onDrop: (acceptedFiles) => {
        setFiles(
          acceptedFiles.map((file) => {
            return Object.assign(file, {
              preview: URL.createObjectURL(file),
              title: file.size,
            });
          })
        );
      },
    });

    return (
      <div {...getRootProps({ className: 'dropzone' })}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
        <button type="button" onClick={open}>
          Open File Dialog
        </button>
      </div>
    );
  };

  useEffect(() => {
    files.forEach((file) => {
      exifr.parse(file, true).then((a) => {
        const eData = {
          title: a.Caption,
          description: a.Description,
          keywords: a.Keywords,
          author: a.Author,
          dateCreated: a.DateCreated,
        };

        formData.files.push(eData);
        setFormData(formData);
      });
    });
  }, [files, formData]);

  console.log(formData);

  return (
    <Create {...props}>
      <SimpleForm initialValues={formData}>
        <ArrayInput source="files">
          <SimpleFormIterator addButton={<AddDropZone />}>
            <TextInput source="title" initialValue="title2" />
            <TextInput source="description" multiline />
            <TextInput source="keywords" multiline />
            <TextInput source="author" />
            <DateInput label="Publication date" source="dateCreated" initialValue={new Date()} />
          </SimpleFormIterator>
        </ArrayInput>
      </SimpleForm>
    </Create>
  );
};