react-dropzone:防止内部元素显示文件选择器

react-dropzone: prevent inner element from showing file picker

我目前正在使用 react-dropzone 插件并遇到了文档中未准确描述的用例。

基本上,我有以下要素:

我现在遇到的问题是在单击 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.