在此React教程中,我将向您展示使用react-dropzone,Axios和Multipart文件来构建拖放文件上传示例,用于制作http请求,for Progress bar for Progress bar for Progress bar和显示文件列表(使用下载列表) URL)。
来自BezKoder。
概述
我们将通过React示例创建一个拖放文件上传该用户可以:
- 拖放文件并将其放入Drop Zone
- 请参阅带有进度栏的上传过程(百分比)
- 查看所有上传的文件
- 单击文件名时下载链接到文件
拖放文件后立即进入Dropzone:
单击上传按钮:
技术
- React 18/17/16
- Axios
- React-Dropzone 11.4.0
- Bootstrap 4
用于文件上传和存储的REST API
这是我们的React应用程序可以使用的API:
方法 | urls | 动作 |
---|---|---|
POST | /upload | 上传文件 |
get | /files | 获取文件列表(名称和URL) |
get | /files/[filename] | 下载文件 |
您可以在以下帖子之一中找到如何实现REST API服务器:
- Node.js Express File Upload Rest API example
- Node.js Express File Upload to MongoDB example
- Node.js Express File Upload to Google Cloud Storage example
- Spring Boot Multipart File upload (to static folder) example
或:Spring Boot Multipart File upload (to database) example
react拖放文件上传应用程序
构建了react.js项目后,文件夹结构将看起来像这样:
让我简要解释。
- fileuploadservice 提供了保存文件并使用Axios获取文件的功能。
- fileupload 包含文件上传滴度,进度栏,列表文件的显示。
-
app.js 是我们嵌入所有反应组件的容器。
-
http-common.js 用http base URL和标头初始化Axios。
-
我们在 .env
中为应用程序配置端口
设置拖动文件上传项目
在要保存项目文件夹的文件夹中打开CMD,运行命令:
npx create-react-app drag-drop-file-upload-react-hooks
完成后。我们创建其他文件夹和文件,例如以下树:
公共
src
- 组件
---- fileupload.js
- 服务
---- fileuploadservice.js
-app.css
-App.js
-index.js
package.json
导入引导程序以备用拖放文件上传应用程序
运行命令:yarn add bootstrap@4.6.0
或:npm install bootstrap@4.6.0
。
打开 src / app.js 并将其内部的代码修改为以下 -
import React from "react";
import "./App.css";
import "bootstrap/dist/css/bootstrap.min.css";
function App() {
return (
...
);
}
export default App;
初始化React HTTP客户端的Axios
让我们安装 axios 带有命令:
yarn add axios
或npm install axios
。
在 src 文件夹下,我们创建 http-common.js 文件,带有以下代码:
import axios from "axios";
export default axios.create({
baseURL: "http://localhost:8080",
headers: {
"Content-type": "application/json"
}
});
您可以更改取决于服务器配置的REST API URL的baseURL
。
为文件上传创建服务
此服务将使用AXIOS发送HTTP请求。
有2个功能:
-
uploadFile(file)
:发布表单数据,带有用于跟踪上传进度的回调 -
getFiles()
:获取文件列表的信息
服务/ fileuploadservice.js
import http from "../http-common";
export const uploadFile = (file, onUploadProgress) => {
let formData = new FormData();
formData.append("file", file);
return http.post("/upload", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
onUploadProgress,
});
};
export const getFiles = () => {
return http.get("/files");
};
-
首先,我们从 http-common.js 。
-
在
uploadFile()
方法中,我们使用FormData
存储键值对。它有助于使用append()
方法构建对应于HTML表单的对象。 -
我们通过
onUploadProgress
揭露进度事件。此进度事件很昂贵(每个事件的更改检测),因此只有在要监视时才能使用。 -
我们致电Axios
post()
发送HTTP帖子,以将文件上传到REST APIS服务器和HTTP的get()
方法for HTTP获取请求以检索所有存储的文件。
安装react-dropzone
添加 react-dropzone 模块纳入命令:
yarn add react-dropzone
- 或:
npm install react-dropzone
创建用于上传文件的页面
让我们创建一个使用进度栏,卡,按钮和消息的文件上传UI。
首先,我们创建一个具有React Hooks(useState
,useEffect
)和导入react-dropzone
的React模板,FileUploadService
功能:
组件/ fileupload.js
import React, { useState, useEffect } from "react";
import Dropzone from "react-dropzone";
import { getFiles, uploadFile } from "../services/FileUploadService";
const UploadFiles = () => {
return (
);
};
export default UploadFiles;
然后我们使用React钩子定义状态:
const UploadFiles = () => {
const [selectedFiles, setSelectedFiles] = useState(undefined);
const [currentFile, setCurrentFile] = useState(undefined);
const [progress, setProgress] = useState(0);
const [message, setMessage] = useState("");
const [fileInfos, setFileInfos] = useState([]);
...
}
接下来,我们定义onDrop()
方法,该方法可帮助我们以后从元素获取所选文件。
const UploadFiles = () => {
...
const onDrop = (files) => {
if (files.length > 0) {
setSelectedFiles(files);
}
};
...
}
我们使用selectedFiles
将当前文件作为第一个项目。然后,我们使用回调在currentFile
上调用UploadService.uploadFile()
方法。因此,创建以下upload()
方法:
const UploadFiles = () => {
...
const upload = () => {
let currentFile = selectedFiles[0];
setProgress(0);
setCurrentFile(currentFile);
uploadFile(currentFile, (event) => {
setProgress(Math.round((100 * event.loaded) / event.total));
})
.then((response) => {
setMessage(response.data.message);
return getFiles();
})
.then((files) => {
setFileInfos(files.data);
})
.catch(() => {
setProgress(0);
setMessage("Could not upload the file!");
setCurrentFile(undefined);
});
setSelectedFiles(undefined);
};
...
}
将基于event.loaded
和event.total
的进度计算。
如果完成了传输,我们将调用UploadService.getFiles()
以获取文件的信息并将结果分配给fileInfos
状态,该状态是{name, url}
对象的数组。
我们还需要在效果hook useEffect()
方法中完成这项工作,该方法具有与componentDidMount()
相同的目的:
const UploadFiles = () => {
...
useEffect(() => {
getFiles().then((response) => {
setFileInfos(response.data);
});
}, []);
...
}
现在我们返回上传文件UI。在return()
块中添加以下代码:
const UploadFiles = () => {
...
return (
<div>
{currentFile && (
<div className="progress mb-3">
<div
className="progress-bar progress-bar-info progress-bar-striped"
role="progressbar"
aria-valuenow={progress}
aria-valuemin="0"
aria-valuemax="100"
style={{ width: progress + "%" }}
>
{progress}%
</div>
</div>
)}
<Dropzone onDrop={onDrop} multiple={false}>
{({ getRootProps, getInputProps }) => (
<section>
<div {...getRootProps({ className: "dropzone" })}>
<input {...getInputProps()} />
{selectedFiles && selectedFiles[0].name ? (
<div className="selected-file">
{selectedFiles && selectedFiles[0].name}
</div>
) : (
"Drag and drop file here, or click to select file"
)}
</div>
<aside className="selected-file-wrapper">
<button
className="btn btn-success"
disabled={!selectedFiles}
onClick={upload}
>
Upload
</button>
</aside>
</section>
)}
</Dropzone>
<div className="alert alert-light" role="alert">
{message}
</div>
{fileInfos.length > 0 && (
<div className="card">
<div className="card-header">List of Files</div>
<ul className="list-group list-group-flush">
{fileInfos.map((file, index) => (
<li className="list-group-item" key={index}>
<a href={file.url}>{file.name}</a>
</li>
))}
</ul>
</div>
)}
</div>
);
};
在上面的代码中,我们使用Bootstrap Progress Bar:
-
.progress
作为包装纸 - 内部
.progress-bar
指示进度 -
.progress-bar
要求style
按百分比设置宽度 -
.progress-bar
还需要role
和一些ARIA属性才能使其可访问 - 进度条的标签是其中的文字
要显示上传文件的列表,我们使用map()
函数在fileInfos
阵列上迭代。在每个文件项上,我们使用file.url
作为href
属性和file.name
显示文本。
不要忘记导出功能组件:
const UploadFiles = () => {
...
}
export default UploadFiles;
dropzone和file
的CSS样式 open app.css 并添加以下样式:
.dropzone {
text-align: center;
padding: 30px;
border: 3px dashed #eeeeee;
background-color: #fafafa;
color: #bdbdbd;
cursor: pointer;
margin-bottom: 20px;
}
.selected-file-wrapper {
text-align: center;
}
.selected-file {
color: #000;
font-weight: bold;
}
将拖放文件上传组件添加到应用程序组件
open app.js ,导入并嵌入UploadFiles
组件标签。
import React from "react";
import "./App.css";
import "bootstrap/dist/css/bootstrap.min.css";
import FileUpload from "./components/FileUpload";
function App() {
return (
<div className="container" style={{ width: "600px" }}>
<div className="my-3">
<h3>bezkoder.com</h3>
<h4>React Drag & Drop File Upload</h4>
</div>
<FileUpload />
</div>
);
}
export default App;
配置React App
的端口由于大多数HTTP服务器都使用CORS配置,该配置接受了限于某些站点或端口的资源共享,因此您需要为我们的应用程序配置端口。
在项目文件夹中,创建 .env 文件,带有以下内容:
PORT=8081
,我们的应用将在端口8081运行。
运行应用程序
您可以在以下帖子之一中找到如何实现REST API服务器:
- Node.js Express File Upload Rest API example
- Node.js Express File Upload to MongoDB example
- Node.js Express File Upload to Google Cloud Storage example
- Spring Boot Multipart File upload (to static folder) example
使用命令:yarn start
或npm run start
。
使用url http://localhost:8081/
打开浏览器并检查结果。
结论
今天,我们学会了如何使用React-Dropzone,Axios,带有Progress Bar的Bootstrap构建React Hooks应用程序,以上传DAB和DRAP文件上传。我们还提供了显示文件列表,上传进度百分比和从服务器下载文件的能力。
对于这样的多个文件上传:
请访问:
React Hooks Multiple File upload example with Axios & Progress Bar
使用React组件:
React Drag and Drop File Upload example
快乐学习!再次见。
进一步阅读
更多练习:
- React Custom Hook
- React File Upload/Download example with Spring Boot Rest Api
- React Hooks CRUD example with Axios and Web API
- React Form Validation with Hooks example
- React Hooks: JWT Authentication (without Redux) example
- React + Redux: JWT Authentication example
Fullstack:
- React + Spring Boot + MySQL: CRUD example
- React + Spring Boot + PostgreSQL: CRUD example
- React + Spring Boot + MongoDB: CRUD example
- React + Node.js + Express + MySQL: CRUD example
- React + Node.js + Express + PostgreSQL example
- React Redux + Node.js + Express + MySQL: CRUD example
- React + Node.js + Express + MongoDB example
- React + Django + Rest Framework example
无服务器:
源代码
您可以在Github上找到本教程的完整源代码。