将文件拖到拖放区时闪烁

Flickering while dragging a file over drop zone

我正在尝试实现 window 仅当您将文件拖到其上时才显示填充 window 的放置区域的效果,而当您取消拖放时则消失文件。

几乎所有 react-dropzone 示例都展示了一个始终可见的拖放区,这不是我想要的。

查看此 CodeSandbox 以了解问题

https://codesandbox.io/s/boring-buck-2fwm6?file=/src/App.js

或在此处查看代码:

import React from "react";
import "./styles.css";
import { useDropzone } from "react-dropzone";
import { Box, makeStyles, createStyles } from "@material-ui/core";

const useStyles = makeStyles(theme =>
  createStyles({
    dropZone: {
      flex: 1,
      display: "flex",
      flexDirection: "column",
      alignItems: "center",
      // padding: "20px",
      borderWidth: 2,
      borderRadius: 2,
      borderColor: "#eeeeee",
      borderStyle: "dashed",
      backgroundColor: "#fafafa",
      color: "#bdbdbd",
      outline: "none",
      transition: "border .24s ease-in-out",
      position: "absolute",
      width: "calc(100% - 4px)",
      height: "calc(100% - 4px)",
      zIndex: 10
    }
  })
);
const useDropzoneInternal = () => {
  const { getRootProps, getInputProps, isDragActive, open } = useDropzone({
    noClick: true
  });
  const inputProps = getInputProps();
  const { ref, ...rootProps } = getRootProps();
  return { rootProps, inputProps, ref, open, isDragActive };
};

export default function App() {
  const classes = useStyles();
  let { rootProps, isDragActive, inputProps } = useDropzoneInternal();

  return (
    <div className="App">
      <Box
        {...rootProps}
        display="flex"
        flexDirection="column"
        flexGrow={1}
        position="relative"
      >
        {isDragActive && (
          <Box className={classes.dropZone}>
            <Box>
              <input {...inputProps} />
              {<p>Drop the files here ...</p>}
            </Box>
          </Box>
        )}
        <h1>Hello CodeSandbox</h1>
        <h2>Drag a file here!</h2>
        <h2>Unfortunately, the drop zone appears and disappears</h2>
        <h2>Because the gray area covers the parent</h2>
        <h2>And hijack the onDragEvent</h2>
        <h2>Start editing to see some magic happen!</h2>
        <h2>Start editing to see some magic happen!</h2>
        <h2>Start editing to see some magic happen!</h2>
        <h2>Start editing to see some magic happen!</h2>
        <h2>Start editing to see some magic happen!</h2>
      </Box>
    </div>
  );
}

isDragActivetrue 时,您可以看到我正在显示拖放区,但它会立即翻转回 false 因为新显示的区域覆盖了父区域div(并且可能取消了拖动事件)。

我该如何解决这个问题?有什么建议吗?

我发现缺少了什么,正如我所料,它很愚蠢,你需要将 ref 传递给决定拖动事件边界的父元素。

  let { ref, rootProps, isDragActive, inputProps } = useDropzoneInternal();

  return (
    <div className="App" ref={ref}>

或者如果你想坚持 Material UI 组件:

<div className="App">
  <RootRef rootRef={ref}>
    <Box
      {...rootProps}
      display="flex"
      flexDirection="column"

我的印象是它不是必需的,如果你销毁父 div 上的 {...rootProps} 就会分配它。