如何从react-dropzone中删除文件?

问题描述 投票:0回答:5

希望你能帮助我,我正在使用 react-dropzone 中的 useDropzone 钩子,我不知道如何为每个文件创建一个删除文件按钮。

如何删除单个文件?

这是我的代码:

function DragFile(props) {
  const { acceptedFiles, rejectedFiles, getRootProps, getInputProps } = useDropzone({
    accept: 'image/jpeg, image/png, .pdf',
    maxSize: 3000000,
    multiple: true
  });

  const acceptedFilesItems = acceptedFiles.map(file => (
    <Col xs={12} md={4} key={file.path} className="card-file">
      <div className="file-extension">{file.path.substring(file.path.indexOf('.') + 1)}</div>
      <span>{file.path.substring(0, file.path.indexOf('.'))} <small>{(file.size / 1000).toFixed(2)} Kb</small></span>
      <button className="delete">DeleteButton</button>
    </Col>
  ));

  const rejectedFilesItems = rejectedFiles.map(file => (
    <li key={file.path}>
      {file.path.substring(0, file.path.indexOf('.'))} - {file.size / 1000} Kb
    </li>
  ));

  return (
    <div>
      <div {...getRootProps({ className: 'dropzone drag-n-drop' })}>
        <input id="file-claim" {...getInputProps()} />
        <img src={uploadSrc} alt="Subir archivo" />
        <p>Drag files here (PDF, JPG, PNG).</p>
      </div>
      <Row className="accepted-files">
        {acceptedFilesItems}
      </Row>
    </div>
  );
}

export default DragFile;
reactjs react-dropzone
5个回答
16
投票

让我添加这段代码,因为这里的其他答案我不清楚:

您需要创建自己的 myFiles 状态并使用 onDrop 函数更新它,然后使用删除函数从本地状态中删除该文件。

import React, { useState, useCallback } from "react"
import { useDropzone } from "react-dropzone"

function Basic(props) {
  const [myFiles, setMyFiles] = useState([])

  const onDrop = useCallback(acceptedFiles => {
    setMyFiles([...myFiles, ...acceptedFiles])
  }, [myFiles])

  const { getRootProps, getInputProps } = useDropzone({
    onDrop,
  })

  const removeFile = file => () => {
    const newFiles = [...myFiles]
    newFiles.splice(newFiles.indexOf(file), 1)
    setMyFiles(newFiles)
  }

  const removeAll = () => {
    setMyFiles([])
  }

  const files = myFiles.map(file => (
    <li key={file.path}>
      {file.path} - {file.size} bytes{" "}
      <button onClick={removeFile(file)}>Remove File</button>
    </li>
  ))

  return (
    <section className="container">
      <div {...getRootProps({ className: "dropzone" })}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
      </div>
      <aside>
        <h4>Files</h4>
        <ul>{files}</ul>
      </aside>
      {files.length > 0 && <button onClick={removeAll}>Remove All</button>}
    </section>
  )
}

export default Basic

6
投票

您可能已经开始工作,但您只需将其附加到点击处理程序即可:

const remove = file => {
  const newFiles = [...files];     // make a var for the new array
  newFiles.splice(file, 1);        // remove the file from the array
  setFiles(newFiles);              // update the state
};

并传递地图上的号码:

acceptedFiles.map(file...
应该是
acceptedFiles.map((file, i)....

然后有

<button type="button" onClick={() => remove(i)> DeleteButton</button>
,其中
i
是数组中文件的编号。


3
投票

我希望这对你有帮助:

import React, { useState, useEffect, useCallback } from 'react'
import { useDropzone } from 'react-dropzone'

const CreateFileUpload = () => {
  const onDrop = useCallback(acceptedFiles => {
    // Do something with the files
  }, [])
  const { getRootProps, getInputProps, isDragActive, acceptedFiles } = useDropzone({ onDrop, accept: '.png, .jpeg' })
  const files = acceptedFiles.map((file, i) => (
    <li key={file.path} className="selected-file-item">
      {file.path}  <i className="fa fa-trash text-red" onClick={() => remove(i)}></i>
    </li>
  ));
  const remove = file => {
    const newFiles = [...files];     // make a var for the new array
    acceptedFiles.splice(file, 1);        // remove the file from the array
  };
  return (
    <div>
      <div {...getRootProps()} className="dropzone-main">
        <div
          className="ntc-start-files-dropzone"
          aria-disabled="false"
        >
        </div>
        <button className="add-button" type="button">
          <i className="fa fa-plus"></i>
        </button>
        <h3 className="upload-title">
          <span></span>
        </h3>
        <input
          type="file"
          multiple=""
          autocomplete="off"
          className="inp-file"
          // onChange={uploadFile}
          multiple
          {...getInputProps()}
        />
        {isDragActive ?
          <div></div>
          :
          <div>
            <p>  Upload files  </p>
          </div>
        }
      </div>
      <aside>
        {files.length > 0 ? <h5>Selected Files</h5> : <h5></h5>}
        <ul>{files}</ul>
      </aside>
    </div>
  )
}
export default CreateFileUpload

0
投票

当您删除文件时,将该数据添加到您的状态,它应该允许您访问该数据,以便您可以删除。

大致:

onDrop = (files) => {
  // use a foreach loop get the file name using Object.keys
  // setState with the file names
  // whatever else you need to do to process the file
}

handleDelete = () => {
  // use the file names from your state to delete the files
}

在某个地方你必须将它们与 jsx 结合起来。您还需要使其与发送到服务器的任何内容保持同步。这一切都应该通过您的组件状态来完成。


0
投票

这里的所有答案都有一个缺陷——如果您添加一个文件,删除它,然后再次添加相同的文件,它将不起作用,因为文件输入上没有触发

change
事件(因为您没有清除出来)

需要从钩子上抓住

inputRef
并在删除按钮中将其清除

function DragFile(props) {
  const [myFile, setMyFile] = useState();
  const { getRootProps, getInputProps, inputRef } = useDropzone({
    onDrop: () => { /* setMyFile */ }
    ...
  });

  return (
    <div>
      {!myFile ? (
        <div {...getRootProps()}>
          <input id="file-claim" {...getInputProps()} />
          drop files here
        </div>
      ) : (
        {myFile.filename}
        <button onClick={() => {
          setMyFile(undefined);
          inputRef.current.value = "";
        }}>remove</button>
      )}
    </div>
  );
}

export default DragFile;
© www.soinside.com 2019 - 2024. All rights reserved.