发布于 2026-01-06 3 阅读
0

使用 React Hooks 实现多个文件输入框和一个提交按钮

使用 React Hooks 实现多个文件输入框和一个提交按钮

最近我做了一个项目,需要实现多个文件输入框。每个输入框只能接受一个特定类型的文件,在我的项目中是只接受pdfjpeg格式。用户上传文件后,需要点击一个提交按钮将所有上传的文件一起提交。但实际上,用户不需要一次性上传所有文件。

我首先想到的是使用`get_file_id` FormData;但是,我需要提交一个对象数组,每个对象都应该包含`file_Id`和文件本身,在我们的例子中,我们称之为`uploaded_file`。`get_file_id`FormData无法做到这一点,所以我只能自己想办法。

在这个例子中,我假设你熟悉Reactjshooks

以下是我为实现目标所采取的步骤:

1.创建一个包含3 个输入文件的 React 组件,每个输入文件仅接受pdfjpeg 格式的文件,并带有唯一的 ID。此外,我们还需要1 个提交按钮。

import React from 'react';

const MultipleFileInput = () => {
  return (
    <form className="upload--container">
      <div className="upload--button">
        <input id={1} accept=".jpeg, .pdf" type="file" />
      </div>
      <div className="upload--button">
        <input id={2} accept=".jpeg, .pdf" type="file" />
      </div>
      <div className="upload--button">
        <input id={3} accept=".jpeg, .pdf" type="file" />
      </div>
      <button type="submit">Submit</button>
    </form>
  );
};

export default MultipleFileInput;
Enter fullscreen mode Exit fullscreen mode

2.创建用于保存对象数组的状态。

  // state that will hold the Array of objects
  // initialized with empty array
  const [files, setFiles] = useState([]);
Enter fullscreen mode Exit fullscreen mode

3.为每个输入文件添加 onChangeHandler。为了读取这些文件,我使用了FileReaderFileReader Web API。

// onChange function that reads files on uploading them
// files read are encoded as Base64
  function onFileUpload(event) {
    event.preventDefault();
    // Get the file Id
    let id = event.target.id;
    // Create an instance of FileReader API
    let file_reader = new FileReader();
    // Get the actual file itself
    let file = event.target.files[0];
    file_reader.onload = () => {
    // After uploading the file
    // appending the file to our state array
    // set the object keys and values accordingly
      setFiles([...files, { file_id: id, uploaded_file: file_reader.result }]);
    };
   // reading the actual uploaded file
    file_reader.readAsDataURL(file);
  }
Enter fullscreen mode Exit fullscreen mode

4.现在让我们实现提交按钮,在这个例子中,我们只是在控制台中记录结果;但是,我必须将这些文件发送到服务器。

  // handle submit button for form
  function handleSubmit(e) {
    e.preventDefault();
    console.log(files)
  }
Enter fullscreen mode Exit fullscreen mode

5.最后,让我们为逻辑添加一些限制。例如,如果没有上传文件,则禁用提交按钮。

// button state whether it's disabled or enabled
  const [enabled, setEnabled] = useState(false);
  // using useEffect we can detect if user uploaded any file, 
  // so enable submit button
  useEffect(() => {
    if (files.length === 0) {
      setEnabled(false);
    } else {
      setEnabled(true);
    }
  }, [files]);
// render submit button based on its state. 
{enabled ? (
        <button type="submit">Submit</button>
      ) : (
        <button disabled type="submit">
          Submit
        </button>
 )}
Enter fullscreen mode Exit fullscreen mode

这最终就是全部代码了。

codesandox链接


import React, { useState, useEffect } from 'react';

const MultipleFileInput = () => {
  // state that will hold the Array of objects
  // initialized with empty array
  const [files, setFiles] = useState([]);
  // onChange function that reads files on uploading them
  // files read are encoded as Base64
  function onFileUpload(event) {
    event.preventDefault();
    // Get the file Id
    let id = event.target.id;
    // Create an instance of FileReader API
    let file_reader = new FileReader();
    // Get the actual file itself
    let file = event.target.files[0];
    file_reader.onload = () => {
      // After uploading the file
      // appending the file to our state array
      // set the object keys and values accordingly
      setFiles([...files, { file_id: id, uploaded_file: file_reader.result }]);
    };
    // reading the actual uploaded file
    file_reader.readAsDataURL(file);
  }
  // handle submit button for form
  function handleSubmit(e) {
    e.preventDefault();
    console.log(files);
  }
  // button state whether it's disabled or enabled
  const [enabled, setEnabled] = useState(false);
  // using useEffect we can detect if user uploaded any file,
  // so enable submit button
  useEffect(() => {
    if (files.length === 0) {
      setEnabled(false);
    } else {
      setEnabled(true);
    }
  }, [files]);

  return (
    <form onSubmit={handleSubmit} className="upload--container">
      <h1> Multiple File Inputs with Signle Submit Button </h1>
      <div className="upload--button">
        <input
          onChange={onFileUpload}
          id={1}
          accept=".jpeg, .pdf"
          type="file"
        />
      </div>
      <div className="upload--button">
        <input
          onChange={onFileUpload}
          id={2}
          accept=".jpeg, .pdf"
          type="file"
        />
      </div>
      <div className="upload--button">
        <input
          onChange={onFileUpload}
          id={3}
          accept=".jpeg, .pdf"
          type="file"
        />
      </div>
      {enabled ? (
        <button type="submit">Submit</button>
      ) : (
        <button disabled type="submit">
          Submit
        </button>
      )}
    </form>
  );
};

export default MultipleFileInput;
Enter fullscreen mode Exit fullscreen mode

结语

如果有人能分享不同的方法,或者对我的现有实现方案提出任何修改意见,我将不胜感激。所以,请不要犹豫,分享您的想法。

文章来源:https://dev.to/fadiamg/multiple-file-inputs-with-one-submit-button-with-react-hooks-kle