使用react-dropzone时,如何在一页上有多个预览多个图像的dropzone?

ndu*_*dub 6 reactjs react-dropzone

我在我的应用程序上使用react-dropzone,并希望在一页上有多个dropzone来预览多个图像。例如,我希望能够将英雄图像拖放到在页面顶部显示英雄图像的放置区。然后,我想将不同的图像放到不同的放置区上,该放置区在缩略图容器中显示图像。

import React, { useState, useMemo, useEffect } from "react";
import Container from "../components/Container";
import { useDropzone } from "react-dropzone";

const Test = () => {
  // Dropzone
  const baseStyle = {
    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",
  };

  const activeStyle = {
    borderColor: "#2196f3",
  };

  const acceptStyle = {
    borderColor: "#00e676",
  };

  const rejectStyle = {
    borderColor: "#ff1744",
  };

  const [files, setFiles] = useState({});
  const { getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject } = useDropzone({
    accept: "image/*",
    onDrop: (acceptedFiles) => {
      console.log(acceptedFiles);
      setFiles(
        Object.assign(acceptedFiles[0], {
          preview: URL.createObjectURL(acceptedFiles[0]),
        })
      );
    },
  });

  const style = useMemo(
    () => ({
      ...baseStyle,
      ...(isDragActive ? activeStyle : {}),
      ...(isDragAccept ? acceptStyle : {}),
      ...(isDragReject ? rejectStyle : {}),
    }),
    [isDragActive, isDragReject, isDragAccept]
  );

  useEffect(
    () => () => {
      // Make sure to revoke the data uris to avoid memory leaks
      URL.revokeObjectURL(files.preview);
    },
    [files]
  );

  return (
    <Container>
      {/* This would be the dropzone for the Hero image */}
      <div>
        <div {...getRootProps({ style })}>
          <input {...getInputProps()} />
          <span style={{ fontSize: ".8rem" }}>Drop hero image here, or click to select file</span>
        </div>
      </div>

      {/* This would be the dropzone for the Thumbnail image */}
      <div>
        <div {...getRootProps({ style })}>
          <input {...getInputProps()} />
          <span style={{ fontSize: ".8rem" }}>Drop hero image here, or click to select file</span>
        </div>
      </div>

      {/* This would be where the Hero image is displayed */}
      <img
        style={{ width: "600px", height: "200px", margin: "0", display: "block" }}
        src={files.preview ? files.preview : "https://via.placeholder.com/600x200"}
        alt="Hero Image"
      />

      {/* This would be where the Thumbnail image is displayed */}
      <img
        style={{ width: "600px", height: "200px", margin: "0", display: "block" }}
        src={files.preview ? files.preview : "https://via.placeholder.com/600x200"}
        alt="Thumbnail Image"
      />
    </Container>
  );
};

export default Test;

Run Code Online (Sandbox Code Playgroud)

我猜我需要修改 onDrop 函数,但我不知道如何做到这一点。任何帮助将不胜感激!

小智 5

  • 创建两个单独的文件变量并分别处理它们。

  • 在两个输入上使用两个单独的 getRootsProps 和 getInputProps 。

     const [file, setFile] = useState({}); 
     const [fileGallery, setFileGallery] = useState({}); 
    
     const { getRootProps:getRootfileProps, getInputProps:getInputfileProps  } = useDropzone({
         accept: 'image/*',
         onDrop: (acceptedFile) => {
             setFile(
                 Object.assign(acceptedFile[0], {
                     preview: URL.createObjectURL(acceptedFile[0]),
                 }),
             );
         },
     });
    
     const { getRootProps:getRootGalleryProps, getInputProps:getInputGalleryProps } = useDropzone({
         accept: 'image/*',
         onDrop: (acceptedFile) => {
             setFileGallery(
                 Object.assign(acceptedFile[0], {
                     preview: URL.createObjectURL(acceptedFile[0]),
                 }),
             );
         },
     });
    
    
     return (
         <Container>
         {/* This would be the dropzone for the Hero image */}
         <div>
             <div {...getRootfileProps({ style })}>
             <input {...getInputfileProps()} />
             <span style={{ fontSize: ".8rem" }}>Drop hero image here, or click to select file</span>
             </div>
         </div>
    
         {/* This would be the dropzone for the Thumbnail image */}
         <div>
             <div {...getRootGalleryProps({ style })}>
             <input {...getInputGalleryProps()} />
             <span style={{ fontSize: ".8rem" }}>Drop hero image here, or click to select file</span>
             </div>
         </div>
    
         {/* This would be where the Hero image is displayed */}
         <img
             style={{ width: "600px", height: "200px", margin: "0", display: "block" }}
             src={files.preview ? files.preview : "https://via.placeholder.com/600x200"}
             alt="Hero Image"
         />
    
         {/* This would be where the Thumbnail image is displayed */}
         <img
             style={{ width: "600px", height: "200px", margin: "0", display: "block" }}
             src={files.preview ? files.preview : "https://via.placeholder.com/600x200"}
             alt="Thumbnail Image"
         />
         </Container>
     );
     };
    
     export default Test;
    
    Run Code Online (Sandbox Code Playgroud)


smi*_*ile 0

您应该在状态上使用两个单独的文件名,其中一个用于英雄,一个用于缩略图,并为每个拖放区管理每个文件名,如下所示:

const [heroFiles, setHeroFiles] = useState({});
const [filesThumb, setFilesThumb] = useState({});
Run Code Online (Sandbox Code Playgroud)