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

问题描述

我目前正在使用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 1source 2)应该避免使用它。我尝试在内部按钮中使用noClick: true,但是它不起作用-很有可能是因为它无法停止父级的<input>标签

除了使用stopPropagation之外,还有其他方法可以尝试吗?

解决方法

我得到了一个答案on GitHub,并在其他人遇到相同问题的情况下将其张贴在这里。

没有办法解决。您必须使用stopPropagation()来阻止事件使DOM冒泡。您还可以选择在父级上也使用noClick

noClick仅在单击dropzone节点时禁用打开文件选择器。这不会阻止事件冒泡。

我们唯一可以做的就是提供一个调用noClickBubbling的{​​{1}}选项,但是用户已经可以这样做。