微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

React js react-dropzone 页面加载时自动打开

如何解决React js react-dropzone 页面加载时自动打开

我正在使用 react-dropzone,我想在页面加载后立即自动打开文件上传对话框。

我编写了以下代码,但我无法理解如何让它自动打开,这是我对 ref 做错了,因为我可以访问它的属性

你能帮我一把吗?

链接

asdf

import React from "react";
import { useDropzone } from "react-dropzone";
import { Chip } from "@material-ui/core";
import { AttachFile } from "@material-ui/icons";

const Dropzone = React.forwardRef(
  ({ multiple = false,onoperation,onDelete },ref) => {
    const [myFile,setMyFile] = React.useState([]);

    const inputRef = React.useRef(null);
    //const inputRef = React.createRef();
    React.useImperativeHandle(
      ref,() => ({
        upload: () => inputRef.current
      }),[inputRef]
    );

    const onDrop = React.useCallback(
      (acceptedFiles) => {
        setMyFile([...acceptedFiles]);
        onoperation(acceptedFiles);
      },[myFile,onoperation]
    );

    const { getRootProps,getInputProps } = useDropzone({
      onDrop
    });

    const removeAll = () => setMyFile([]);
    const file = myFile.map((file,key) => (
      <Chip
        key={key}
        icon={<AttachFile />}
        label={`${file.path} - ${file.size} bytes`}
        color="primary"
        onDelete={() => {
          removeAll();
          onDelete && onDelete();
        }}
        style={{
          cursor: "pointer",backgroundColor: "#2196f3"
        }}
      />
    ));

    const label = "File";

    return (
      <span {...getRootProps({ className: "drop-zone" })}>
        <input ref={inputRef} {...getInputProps()} multiple={multiple} />
        {file.length > 0 ? (
          file
        ) : (
          <Chip
            icon={<AttachFile />}
            label={label}
            color="primary"
            style={{
              cursor: "pointer",backgroundColor: "#2196f3"
            }}
          />
        )}
      </span>
    );
  }
);

export default function App() {
  const onDrop = (file) => console.log(file);
  //const ref = React.useRef(null);
  const ref = React.createRef();

  React.useEffect(() => {
    console.log("Ref:",ref.current,ref.current.upload());
    /*if (ref.current) {
      ref.current.open();
    }*/
  },[]);

  return (
    <div className="App">
      <Dropzone ref={ref} onoperation={onDrop} />
    </div>
  );
}

解决方法

ref 中创建的 App 是对您的 Dropzone 组件的引用。通过 useImperativeHandle,该 ref 具有一个属性,即 upload —— 一个返回 input 元素或 null 的函数。

不知何故,该值始终为 null。起初我认为问题与执行顺序有关。但不是这样。这是您的 ref={inputRef}{...getInputProps()} 覆盖,其中包括它自己的 ref 属性。如果您切换顺序并将 ref 放在最后,那么您将开始记录 <input> 元素。

但是现在点击图标没有任何作用,因为 react-dropzone 包依赖于我们覆盖的 ref。

幸运的是,useDropzone 钩子返回了一个 inputRef。因此,相同的 ref 可用于内部 react-dropzone 逻辑和自定义逻辑。它还返回一个您可以使用的 open 函数。

我删除了您的 inputRef 并使用了 open 函数作为 ref.upload 的值。

const { getRootProps,getInputProps,open } = useDropzone({
  onDrop
});

React.useImperativeHandle(
  ref,() => ({
    upload: open
  }),[open]
);

点击打开它没有问题。但不幸的是@Marios Nikolaou 的评论是正确的。当我尝试通过 useEffect 打开它时,我在控制台中收到一条警告:

文件选择器对话框只能在用户激活时显示。

所以你想要的东西是不可能的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。