React Dropzone:使用 Dropzone 进行图像拖放

上传文件是大多数 Web 应用程序中的常见功能,而**拖放功能**已成为实现此功能的便捷方式。要在 React 应用程序中实现此功能,**react-dropzone 模块**是一种流行的选择,因为它具有丰富的功能和自定义选项,可以根据个人需求进行定制。

本文旨在深入了解**react-dropzone 模块**,探索利用其功能实现拖放的各种方法,并提供自定义其行为的示例。

**React Dropzone 模块:简介**

**React Dropzone**,也称为 react-dropzone,是一个 React 模块,允许在 React 应用程序中轻松创建拖放功能。此模块简化了用户的文件上传体验,使他们能够将文件从文件资源管理器拖放到应用程序中以立即上传。凭借大量自定义选项,**React Dropzone** 是一个功能丰富的模块。用户可以限制可以上传的文件类型,以及同时上传多个文件等功能。

**如何安装和建模基本的 React Dropzone 文件选择器**

要将 react-dropzone 模块添加到应用程序,我们可以使用以下命令。

`npm install react-dropzone`

此模块非常适合任何涉及文件上传的应用程序,例如大学入学申请网站、求职网站或帖子上传平台。我们的第一步是使用 **React Dropzone** 构建一个基本的文件选择器。

首先,我们应该在文件中所有其他导入下面导入 **React Dropzone 库**。接下来,我们可以在 render 方法的 return 语句中包含 React Dropzone 组件,并在其上方包含 **onDrop** 方法。生成的代码应类似于以下内容:

import React, { Component } from 'react';
import Dropzone from 'react-dropzone'

class App extends Component {

  onDrop = (acceptedFiles) => {
    console.log(acceptedFiles);
  }

  render() {
    return (
      
{({getRootProps, getInputProps}) => (
Click me to upload a file!
)}
); } } export default App;

**React Dropzone** 只需要将一个方法传递到 onDrop 属性中来处理文件选择。为了保持简单性,我们将方法命名为 **onDrop** 以匹配属性名称。

onDrop 方法有一个参数 **acceptedFiles**,我们目前将其记录到控制台以进行测试。保存组件后,我们可以打开浏览器并导航到正在运行的 React 应用程序。

单击文本标签将打开一个**文件选择器**窗口,这是一个很好的开始!但是,此时选择要上传的文件不会有任何效果。要使文件上传功能正常,我们需要将文件发送到服务器,这将在以后的教程中介绍。

**渲染道具**

**React Dropzone 的**外观可能与您遇到的其他 React 组件不同,因为它采用了 Render Props 技术。

Render Prop 函数根据当前状态修改 **Dropzone** 组件内的 HTML。

为了演示这个概念,我们将向 Render Prop 函数添加一个名为 isDragActive 的变量。这个变量允许我们访问 Dropzone 组件的当前拖动状态。

在 **isDragActive** 状态可用的情况下,我们可以改变标签的文本值,以便在文件拖到组件上时显示一些不同的内容


  {({getRootProps, getInputProps, isDragActive}) => (
    
{isDragActive ? "Drop it like it's hot!" : 'Click me or drag a file to upload!'}
)}

上述代码片段演示了一个内联条件,用于检查 **isDragActive** 是否为真。如果为真,则显示文本“**Drop it like it's hot**”,如果为假,则显示文本“**Click me or drag a file to upload!**”。

**允许特定类型的文件**

目前,我们的文件选择器允许我们选择任何文件类型进行上传。

但是,根据文件选择器的用途,我们可能希望将选择限制为特定的文件类型,例如仅 .**JPG** 文件,或仅 .**XLS** 和 .**DOCX** 文件。

为了实现这一点,我们可以使用 accept prop 并将其添加到 **Dropzone** 组件声明中的 **onDrop** 之后。


...

文件类型表示为**MIME 类型**,Mozilla 提供了全面的**MIME 类型**列表。

为了增强我们的文件选择器的用户体验,当用户尝试上传不被接受的文件类型时,我们可以显示一条消息。

我们可以通过添加另一个名为 isDragRejected 的渲染道具并相应地修改内联条件逻辑来实现这一点。


  {({getRootProps, getInputProps, isDragActive, isDragReject}) => (
    
{!isDragActive && 'Click here or drop a file to upload!'} {isDragActive && !isDragReject && "Drop it like it's hot!"} {isDragReject && "File type not accepted, sorry!"}
)}

最后,我们可以保存文件并通过尝试将 .JPG 文件拖到浏览器中的文件选择器上进行测试。当我们这样做时,会显示一条消息,表明我们的文件选择器不接受该类型的文件。

**最大和最小文件大小**

设置文件大小限制至关重要,以防止用户上传过大的文件并导致服务器超载。

React Dropzone 提供两个属性,minSize 和 maxSize,允许您设置文件的最大和最小大小(以字节为单位)。

要指定最大文件大小为 5MB 或更小,请将 minSize 和 maxSize 属性添加到 accept 属性下方的 Dropzone 组件。

App.js

  ...

为了增强用户体验,让我们在文件输入组件中添加一些代码,以验证最大文件大小,如果上传的文件超出限制,则显示错误消息。

render() {
  const maxSize = 1048576;
  return (
    
{({getRootProps, getInputProps, isDragActive, isDragReject, rejectedFiles}) => { const isFileTooLarge = rejectedFiles.length > 0 && rejectedFiles[0].size > maxSize; return (
{!isDragActive && 'Click here or drop a file to upload!'} {isDragActive && !isDragReject && "Drop it like it's hot!"} {isDragReject && "File type not accepted, sorry!"} {isFileTooLarge && (
File is too large.
)}
)} }
); }

尽管看起来代码量很大,但实际上只有几行(通常少于 10 行)。

以下是说明:

  • 我们创建一个名为“maxSize”的常量,并在render方法开始时将其值设置为1MB。
  • 我们在 Dropzone 组件的“maxSize”属性中使用“maxSize”常量。
  • 我们向 Dropzone 组件添加了一个名为“rejectedFiles”的新渲染道具。
  • 在 Dropzone 组件中的 render prop 函数之后,我们定义了另一个常量,名为“isFileTooLarge”。它从“rejectedFiles”数组中检索第一个文件,并检查其大小是否大于我们之前定义的“maxSize”常量。
  • 然后我们使用条件语句检查“isFileTooLarge”是否为真,并以红色显示消息“文件太大”。让我们在浏览器中测试该功能!
  • 多个文件同时运行!

    我们将讨论的关于 React Dropzone 的最后一个功能是上传多个文件的能力。这是一个简单的过程,不涉及对渲染 prop 函数的任何更改。要启用此功能,我们只需将“multiple”prop 添加到 React Dropzone 组件声明中。

    
      ...
    

    **如何在 React Dropzone 中使用 Hooks

    **

    React Hooks 的发布以及带有自定义 useDropzone Hook 的 **react-dropzone 库** 的更新版本促使整个组件被重写为一个功能性组件。

    这涉及使用 react **dropzone** 提供的 **useDropzone** 自定义钩子。

    import React, { useCallback } from 'react';
    import { useDropzone } from 'react-dropzone'
    
    const App = () => {
      const maxSize = 1048576;
    
      const onDrop = useCallback(acceptedFiles => {
        console.log(acceptedFiles);
      }, []);
    
      const { isDragActive, getRootProps, getInputProps, isDragReject, acceptedFiles, rejectedFiles } = useDropzone({
        onDrop,
        accept: 'image/png',
        minSize: 0,
        maxSize,
      });
    
      const isFileTooLarge = rejectedFiles.length > 0 && rejectedFiles[0].size > maxSize;
    
      return (
        
    {!isDragActive && 'Click here or drop a file to upload!'} {isDragActive && !isDragReject && "Drop it like it's hot!"} {isDragReject && "File type not accepted, sorry!"} {isFileTooLarge && (
    File is too large.
    )}
    ); }; export default App;

    **如何显示已接受文件列表

    **

    React Hooks 的可用性以及 react-dropzone 库的更新版本(包括自定义的 **useDropzone Hook**)已导致该组件被完全重写为功能性组件。

    这次重写需要利用 **react-dropzone** 提供的 **useDropzone** 自定义钩子

    ...
    
      {acceptedFiles.length > 0 && acceptedFiles.map(acceptedFile => (
    • {acceptedFile.name}
    • ))}
    ...

    **结论**

    总而言之,**react-dropzone** 是一个广泛使用的 React 模块,可在 Web 应用程序中启用拖放功能。此包提供许多自定义选项,包括限制上传文件大小和允许上传特定文件类型的功能。此外,该包还提供了上传多个文件和轻松显示上传文件列表的功能。使用 **react-dropzone**,我们不必依赖 HTML 拖放 API,这以前是使用拖放上传文件的最常见方式。