You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止react-dropzone中点击删除按钮时弹出文件选择对话框?

问题:react-dropzone删除按钮触发文件选择对话框

使用react-dropzone实现文件上传功能,已上传文件存储在数组中用于展示,每个文件项旁添加的删除按钮点击时,会意外弹出文件选择对话框,需要阻止该行为。

原代码如下:

import { useState } from "react";
import "./styles.css";
import Dropzone from "react-dropzone";
import * as React from "react";

export default function App() {
  const [files, setFiles] = useState([{ name: "test" }]);

  const handleDrop = () => {
    console.log("dropped");
  };

  return (
    <div className="App">
      <h1>React Typescript Tailwind CSS started</h1>

      <Dropzone onDrop={handleDrop}>
        {({ getRootProps, getInputProps }) => (
          <div style={{ border: "2px solid black", height: "100px" }}>
            <div>
              <div {...getRootProps()}>
                <input {...getInputProps()} />

                <button>Select a file</button>

                {files && files.length > 0 && (
                  <ul>
                    {files.map((file) => (
                      <li key={file.name} className="relative w-fit">
                        {file.name}
                        <button onClick={() => console.log("delete")}>
                          delete
                        </button>
                      </li>
                    ))}
                  </ul>
                )}
              </div>
            </div>
          </div>
        )}
      </Dropzone>
    </div>
  );
}
原因分析

删除按钮被包裹在getRootProps()绑定的div内部,这个div是react-dropzone的触发容器,点击该区域内的任何元素都会触发文件选择的默认行为(事件冒泡导致)。

解决方案

方案1:将文件列表移出dropzone触发容器

把展示已上传文件的<ul>从getRootProps()绑定的div中移出,让删除按钮不在触发区域内:

import { useState } from "react";
import "./styles.css";
import Dropzone from "react-dropzone";
import * as React from "react";

export default function App() {
  const [files, setFiles] = useState([{ name: "test" }]);

  const handleDrop = () => {
    console.log("dropped");
  };

  return (
    <div className="App">
      <h1>React Typescript Tailwind CSS started</h1>

      <Dropzone onDrop={handleDrop}>
        {({ getRootProps, getInputProps }) => (
          <div style={{ border: "2px solid black", height: "100px" }}>
            <div>
              <div {...getRootProps()}>
                <input {...getInputProps()} />
                <button>Select a file</button>
              </div>
              {/* 将文件列表移到触发容器外部 */}
              {files && files.length > 0 && (
                <ul>
                  {files.map((file) => (
                    <li key={file.name} className="relative w-fit">
                      {file.name}
                      <button onClick={() => console.log("delete")}>
                        delete
                      </button>
                    </li>
                  ))}
                </ul>
              )}
            </div>
          </div>
        )}
      </Dropzone>
    </div>
  );
}

方案2:阻止删除按钮的事件冒泡

在删除按钮的点击事件中调用e.stopPropagation(),阻止事件传递到dropzone的触发容器:

import { useState } from "react";
import "./styles.css";
import Dropzone from "react-dropzone";
import * as React from "react";

export default function App() {
  const [files, setFiles] = useState([{ name: "test" }]);

  const handleDrop = () => {
    console.log("dropped");
  };

  return (
    <div className="App">
      <h1>React Typescript Tailwind CSS started</h1>

      <Dropzone onDrop={handleDrop}>
        {({ getRootProps, getInputProps }) => (
          <div style={{ border: "2px solid black", height: "100px" }}>
            <div>
              <div {...getRootProps()}>
                <input {...getInputProps()} />

                <button>Select a file</button>

                {files && files.length > 0 && (
                  <ul>
                    {files.map((file) => (
                      <li key={file.name} className="relative w-fit">
                        {file.name}
                        {/* 阻止事件冒泡 */}
                        <button onClick={(e) => {
                          e.stopPropagation();
                          console.log("delete");
                        }}>
                          delete
                        </button>
                      </li>
                    ))}
                  </ul>
                )}
              </div>
            </div>
          </div>
        )}
      </Dropzone>
    </div>
  );
}

内容的提问来源于stack exchange,提问作者Johan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 09:55:31