【问题标题】:How can I have multiple dropzones on one page that preview multiple images when using react-dropzone?使用 react-dropzone 时,如何在一个页面上有多个可以预览多个图像的拖放区?
【发布时间】:2021-02-03 23:42:15
【问题描述】:

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

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;

我猜我需要修改 onDrop 函数,但我不知道该怎么做。任何帮助将不胜感激!

【问题讨论】:

    标签: reactjs react-dropzone


    【解决方案1】:

    您应该在状态上使用两个单独的文件名,一个用于英雄,一个用于缩略图,并为每个放置区管理它们中的每一个 像这样:

    const [heroFiles, setHeroFiles] = useState({});
    const [filesThumb, setFilesThumb] = useState({});
    

    【讨论】:

      【解决方案2】:

      您正在使用 Dropzone 挂钩,这将使您难以实现您的目标,请改用 Dropzone 组件并为您打算使用的每个 Dropzone 输入声明状态。

      import React, { useState } from "react";
      import Container from "../components/Container";
      import Dropzone from "react-dropzone";
      
      const Test = () => {
          const [heroFiles, setHeroFiles] = useState([]);
          const [thumbnailFiles, setThumbnailFiles] = useState([]);
          
          return (
              <Container>
                  {/* This would be the dropzone for the Hero image */}
                  <Dropzone  onDrop={(acceptedFiles) => {
                        setHeroFiles(acceptedFiles.map(file => Object.assign(file, {
                            preview: URL.createObjectURL(file)
                        })));
                     }} name="heroImage" multiple={false}>
                     {({getRootProps, getInputProps}) => (
                         <div {...getRootProps({className: 'dropzone'})}>
                             <input {...getInputProps()} />
                             <span style={{ fontSize: ".8rem" }}>
                                  Drop hero image here, or click to select file
                             </span>
                         </div>
                     )}
                </Dropzone>
                {/* This would be the dropzone for the Thumbnail image */}
                <Dropzone  onDrop={(acceptedFiles) => {
                        setHeroFiles(acceptedFiles.map(file => Object.assign(file, {
                            preview: URL.createObjectURL(file)
                        })));
                     }} name="heroImage" multiple={false}>
                     {({getRootProps, getInputProps}) => (
                         <div {...getRootProps({className: 'dropzone'})}>
                             <input {...getInputProps()} />
                             <span style={{ fontSize: ".8rem" }}>
                                  Drop hero image here, or click to select file
                             </span>
                         </div>
                     )}
                  </Dropzone>
                  {/* This would be where the Hero image is displayed */}
                  <img style={{ width: "600px", height: "200px", margin: "0", display: "block" }} src={heroFiles.length > 0 ? heroFiles[0].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={thumbnailFiles.length > 0  ? thumbnailFiles[0].preview  : "https://via.placeholder.com/600x200"} alt="Thumbnail Image"/>
              </Container>
          );
      }
      
      export default Test;
      

      这应该可以解决您的问题。

      【讨论】:

        【解决方案3】:

        您需要创建两个单独的文件变量并分别处理它们。此外,您在两个输入上都使用了相同的 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]),
                    }),
                  );
                },
              });
        

        【讨论】:

          【解决方案4】:
          • 创建两个单独的文件变量并分别处理。

          • 在两个输入上使用两个单独的 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;
            

          【讨论】:

            猜你喜欢
            • 2017-12-04
            • 1970-01-01
            • 2018-04-18
            • 1970-01-01
            • 2015-09-29
            • 2015-04-21
            • 2017-01-17
            • 1970-01-01
            • 2014-12-26
            相关资源
            最近更新 更多