使用 React Hooks 实现多个文件输入框和一个提交按钮
最近我做了一个项目,需要实现多个文件输入框。每个输入框只能接受一个特定类型的文件,在我的项目中是只接受pdf和jpeg格式。用户上传文件后,需要点击一个提交按钮将所有上传的文件一起提交。但实际上,用户不需要一次性上传所有文件。
我首先想到的是使用`get_file_id` FormData;但是,我需要提交一个对象数组,每个对象都应该包含`file_Id`和文件本身,在我们的例子中,我们称之为`uploaded_file`。`get_file_id`FormData无法做到这一点,所以我只能自己想办法。
在这个例子中,我假设你熟悉Reactjs和hooks。
以下是我为实现目标所采取的步骤:
1.创建一个包含3 个输入文件的 React 组件,每个输入文件仅接受pdf和jpeg 格式的文件,并带有唯一的 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;
2.创建用于保存对象数组的状态。
// state that will hold the Array of objects
// initialized with empty array
const [files, setFiles] = useState([]);
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);
}
4.现在让我们实现提交按钮,在这个例子中,我们只是在控制台中记录结果;但是,我必须将这些文件发送到服务器。
// handle submit button for form
function handleSubmit(e) {
e.preventDefault();
console.log(files)
}
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>
)}
这最终就是全部代码了。
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;
结语
如果有人能分享不同的方法,或者对我的现有实现方案提出任何修改意见,我将不胜感激。所以,请不要犹豫,分享您的想法。
文章来源:https://dev.to/fadiamg/multiple-file-inputs-with-one-submit-button-with-react-hooks-kle