react-dropzone:防止内部元素显示文件选择器
react-dropzone: prevent inner element from showing file picker
我目前正在使用 react-dropzone 插件并遇到了文档中未准确描述的用例。
基本上,我有以下要素:
- 一个应该允许两者的外部降落区
- 拖放和
- 本机文件选择器
on click
- 不显示本机文件选择器的内部按钮
on click
我现在遇到的问题是在单击 inner 按钮时阻止本机文件选择器显示。
为了说明我的示例,您可以将此代码粘贴到 View Code 部分。
import React from 'react';
import {useDropzone} from 'react-dropzone';
function Dropzone(props) {
const {getRootProps, getInputProps, open, acceptedFiles} = useDropzone({
// Disable click and keydown behavior
noKeyboard: true
});
const files = acceptedFiles.map(file => (
<li key={file.path}>
{file.path} - {file.size} bytes
</li>
));
return (
<div className="container">
<div {...getRootProps({className: 'dropzone'})}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here</p>
<InnerButton />
</div>
<aside>
<h4>Files</h4>
<ul>{files}</ul>
</aside>
</div>
);
}
function InnerButton(props) {
const { getRootProps } = useDropzone({ noClick: true }); // doesn't stop the parent's input file picker
return (
<button
{...getRootProps({
onClick: (event) => event.stopPropagation(), // this is bad for many reasons
})}
type="button">
This button should not open the file picker
</button>
);
}
<Dropzone />
我认为使用 event.stopPropagation()
是一种方法,但我读到应该避免使用它,原因有很多 (source 1, source 2)。我尝试在内部按钮中使用 noClick: true
但它不起作用 - 很可能是因为它无法停止父级的 <input>
标签。
除了使用 stopPropagation
之外,还有其他我应该尝试的方法吗?
我得到了答案 on GitHub,张贴在这里以防其他人遇到同样的问题。
There's no way around it. You have to use stopPropagation()
to stop the event from bubbling up the DOM. Your other option is to use noClick
on the parent as well.
noClick
only disables opening the file selector when clicking on the dropzone node. It does not prevent the event from bubbling.
The only thing we can do is to provide a noClickBubbling
option that calls stopPropagation()
, but the user can already do that.
我目前正在使用 react-dropzone 插件并遇到了文档中未准确描述的用例。
基本上,我有以下要素:
- 一个应该允许两者的外部降落区
- 拖放和
- 本机文件选择器
on click
- 不显示本机文件选择器的内部按钮
on click
我现在遇到的问题是在单击 inner 按钮时阻止本机文件选择器显示。
为了说明我的示例,您可以将此代码粘贴到 View Code 部分。
import React from 'react';
import {useDropzone} from 'react-dropzone';
function Dropzone(props) {
const {getRootProps, getInputProps, open, acceptedFiles} = useDropzone({
// Disable click and keydown behavior
noKeyboard: true
});
const files = acceptedFiles.map(file => (
<li key={file.path}>
{file.path} - {file.size} bytes
</li>
));
return (
<div className="container">
<div {...getRootProps({className: 'dropzone'})}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here</p>
<InnerButton />
</div>
<aside>
<h4>Files</h4>
<ul>{files}</ul>
</aside>
</div>
);
}
function InnerButton(props) {
const { getRootProps } = useDropzone({ noClick: true }); // doesn't stop the parent's input file picker
return (
<button
{...getRootProps({
onClick: (event) => event.stopPropagation(), // this is bad for many reasons
})}
type="button">
This button should not open the file picker
</button>
);
}
<Dropzone />
我认为使用 event.stopPropagation()
是一种方法,但我读到应该避免使用它,原因有很多 (source 1, source 2)。我尝试在内部按钮中使用 noClick: true
但它不起作用 - 很可能是因为它无法停止父级的 <input>
标签。
除了使用 stopPropagation
之外,还有其他我应该尝试的方法吗?
我得到了答案 on GitHub,张贴在这里以防其他人遇到同样的问题。
There's no way around it. You have to use
stopPropagation()
to stop the event from bubbling up the DOM. Your other option is to usenoClick
on the parent as well.
noClick
only disables opening the file selector when clicking on the dropzone node. It does not prevent the event from bubbling.The only thing we can do is to provide a
noClickBubbling
option that callsstopPropagation()
, but the user can already do that.