react-use-file-upload 中存在多个输入类型文件

问题描述 投票:0回答:1

我正在使用 react-use-file-upload
下面给出的是文档示例:

import React, { useRef } from 'react';
import axios from 'axios';
import useFileUpload from 'react-use-file-upload';

const Upload = () => {
  const {
    files,
    fileNames,
    fileTypes,
    totalSize,
    totalSizeInBytes,
    handleDragDropEvent,
    clearAllFiles,
    createFormData,
    setFiles,
    removeFile,
  } = useFileUpload();

  const inputRef = useRef();

  const handleSubmit = async (e) => {
    e.preventDefault();

    const formData = createFormData();

    try {
      axios.post('https://some-api.com', formData, {
        'content-type': 'multipart/form-data',
      });
    } catch (error) {
      console.error('Failed to submit files.');
    }
  };

  return (
    <div css={CSS}>
      <h1>Upload Files</h1>

      <p>Please use the form to your right to upload any file(s) of your choosing.</p>

      <div className="form-container">
        {/* Display the files to be uploaded */}
        <div css={ListCSS}>
          <ul>
            {fileNames.map((name) => (
              <li key={name}>
                <span>{name}</span>

                <span onClick={() => removeFile(name)}>
                  <i className="fa fa-times" />
                </span>
              </li>
            ))}
          </ul>

          {files.length > 0 && (
            <ul>
              <li>File types found: {fileTypes.join(', ')}</li>
              <li>Total Size: {totalSize}</li>
              <li>Total Bytes: {totalSizeInBytes}</li>

              <li className="clear-all">
                <button onClick={() => clearAllFiles()}>Clear All</button>
              </li>
            </ul>
          )}
        </div>

        {/* Provide a drop zone and an alternative button inside it to upload files. */}
        <div
          css={DropzoneCSS}
          onDragEnter={handleDragDropEvent}
          onDragOver={handleDragDropEvent}
          onDrop={(e) => {
            handleDragDropEvent(e);
            setFiles(e, 'a');
          }}
        >
          <p>Drag and drop files here</p>

          <button onClick={() => inputRef.current.click()}>Or select files to upload</button>

          {/* Hide the crappy looking default HTML input */}
          <input
            ref={inputRef}
            type="file"
            multiple
            style={{ display: 'none' }}
            onChange={(e) => {
              setFiles(e, 'a');
              inputRef.current.value = null;
            }}
          />
        </div>
      </div>

      <div className="submit">
        <button onClick={handleSubmit}>Submit</button>
      </div>
    </div>
  );
};

但问题是,目前在我的组件中,我有多个输入类型文件。
所以,我很困惑,如何使用这个库来管理所有文件输入。
如果有人已经这样做了,请帮忙!

注意:我想要这样的功能:

<input />
<input />
.
.
.

所有输入均为文件类型。

reactjs
1个回答
0
投票

FileUploader创建可重用组件:

import React, { useEffect, useRef } from 'react';
import useFileUpload from 'react-use-file-upload';

/**
 * @param {*fieldName} props
 * fieldName is related to the unique name of the input field, like profile_pic, id_proof
 * @returns 
 */
const FileUploader = (props) => {
    const { multiple = false, uploadButtonLabel = "Or select files to upload", onFilesSelected, fieldName } = props;
    const {
        files,
        fileNames,
        fileTypes,
        totalSize,
        totalSizeInBytes,
        handleDragDropEvent,
        clearAllFiles,
        createFormData,
        setFiles,
        removeFile,
    } = useFileUpload();

    const inputRef = useRef();


    useEffect(() => {
        if (onFilesSelected) {
            onFilesSelected(files, fieldName); // Pass the selected files and field name to the parent component
        }
    }, [files, onFilesSelected, fieldName]);

    // const handleSubmit = async (e) => {
    //     e.preventDefault();

    //     const formData = createFormData();
    //     try {
    //         console.log('formData', formData);
    //     } catch (error) {
    //     }
    // };

    return (
        <div>
            {/* <h1>Upload Files</h1> */}
            <div className="form-container">
                {/* Display the files to be uploaded */}
                <div>
                    <ul>
                        {fileNames.map((name) => (
                            <li key={name}>
                                <span>{name}</span>
                                <span onClick={() => removeFile(name)}>
                                    <i className="" />
                                </span>
                            </li>
                        ))}
                    </ul>

                    {files.length > 0 && (
                        <ul>
                            <li>File types found: {fileTypes.join(', ')}</li>
                            <li>Total Size: {totalSize}</li>
                            {/* <li>Total Bytes: {totalSizeInBytes}</li> */}

                            <li className="clear-all">
                                <button onClick={() => clearAllFiles()}>Clear All</button>
                            </li>
                        </ul>
                    )}
                </div>

                {/* Provide a drop zone and an alternative button inside it to upload files. */}
                <div
                    onDragEnter={handleDragDropEvent}
                    onDragOver={handleDragDropEvent}
                    onDrop={(e) => {
                        handleDragDropEvent(e);
                        setFiles(e);
                    }}
                >
                    <p>Drag and drop files here</p>

                    <button type="button" onClick={() => inputRef.current.click()}>{uploadButtonLabel}</button>

                    {/* Hide the default HTML input */}
                    <input
                        ref={inputRef}
                        type="file"
                        multiple={multiple}
                        style={{ display: 'none' }}
                        onChange={(e) => {
                            setFiles(e);
                            inputRef.current.value = null;
                        }}
                    />
                </div>
            </div>

            {/* <div className="submit">
        <button onClick={handleSubmit}>Submit</button>
      </div> */}
        </div>
    );
};

export default FileUploader;

然后parentComponent将如下所示:

    const [selectedFiles, setSelectedFiles] = useState([]);

    const handleFilesSelected = (files, fieldName) => {
        setSelectedFiles(prevState => ({
            ...prevState,
            [fieldName]: files
        }));
    };
 <FileUploader
   uploadButtonLabel="Click to Upload"
   onFilesSelected={handleFilesSelected}
   fieldName={"proof_id"}
/>

<FileUploader
   uploadButtonLabel="Click to Upload"
   onFilesSelected={handleFilesSelected}
   fieldName={"address_proof"}
/>
© www.soinside.com 2019 - 2024. All rights reserved.