使用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",display: "block" }}
        src={files.preview ? files.preview : "https://via.placeholder.com/600x200"}
        alt="Thumbnail Image"
      />
    </Container>
  );
};

export default Test;

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

解决方法

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

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