如何阻止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
相关产品推荐
相关产品推荐

