React拖放文件上传示例
#javascript #网络开发人员 #react #todayilearned

在此React教程中,我将向您展示使用react-dropzoneAxiosMultipart文件来构建拖放文件上传示例,用于制作http请求,for Progress bar for Progress bar for Progress bar和显示文件列表(使用下载列表) URL)。

来自BezKoder

概述

我们将通过React示例创建一个拖放文件上传该用户可以:

  • 拖放文件并将其放入Drop Zone
  • 请参阅带有进度栏的上传过程(百分比)
  • 查看所有上传的文件
  • 单击文件名时下载链接到文件

react-drag-and-drop-file-upload-example

拖放文件后立即进入Dropzone:

react-drag-and-drop-file-upload-dropzone

单击上传按钮:

react-drag-and-drop-file-upload-progress-bar

技术

  • 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服务器:

或:Spring Boot Multipart File upload (to database) example

react拖放文件上传应用程序

构建了react.js项目后,文件夹结构将看起来像这样:

react-drag-and-drop-file-upload-project-structure

让我简要解释。

  • 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 axiosnpm 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(useStateuseEffect)和导入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.loadedevent.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服务器:

使用命令:yarn startnpm run start

运行此React客户端。

使用url http://localhost:8081/打开浏览器并检查结果。

结论

今天,我们学会了如何使用React-Dropzone,Axios,带有Progress Bar的Bootstrap构建React Hooks应用程序,以上传DAB和DRAP文件上传。我们还提供了显示文件列表,上传进度百分比和从服务器下载文件的能力。

对于这样的多个文件上传:

react-hooks-multiple-files-upload-example

请访问:
React Hooks Multiple File upload example with Axios & Progress Bar

使用React组件:
React Drag and Drop File Upload example

快乐学习!再次见。

进一步阅读

更多练习:

Fullstack:

无服务器:

源代码

您可以在Github上找到本教程的完整源代码。