ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 케이커 웹/앱 - 4 (파일 업로드, 드래그 앤 드롭)
    프론트엔드 2022. 8. 14. 23:33

    DND 코드,, 이거 구현하려고 일주일이나 걸렸다. 코드 정보가 워낙 없어서 조금 힘들었던😂

    이미지 파일 2개를 한 번에 업로드 해야했어서 js파일에 변수명만 다르게 작업을 해봤지만

    import { useDropzone } from "react-dropzone"
     
    에서 제공하는 변수명이 고정되어 있어서 어쩔 수 없이 컴포넌트 2개로 나누어 작업을 진행했다.
     

     

    Fileupload > ShopImgUpload.js

    import styled from "styled-components";
    import React, { useEffect, useState } from "react";
    import { useDropzone } from "react-dropzone";

    const ShopIntroduceName = styled.div`
      width: 200px;
      height: 22px;
      margin: 30px 0px 0px 24px;
      font-family: "Apple SD Gothic Neo";
      font-style: normal;
      font-weight: 700;
      font-size: 18px;
      line-height: 22px;
      text-transform: uppercase;
      color: #202020;
      z-index: 1;
    `;

    //가게 대표 사진
    const ShopPhoto = styled.p`
      margin: 10px 0px 0px 5%;
      width: 90%;
      height: 100px;
      background: var(--sub-lightgray);
      border-radius: 6px;
      border: 1px solid var(--sub-lightgray);
      text-align: center;
      display: flex;
      justify-content: space-around;
      align-items: center;
      &:hover {
        border: 1px dashed #333;
      }
    `;

    //파일 컴포넌트
    const FileInfo = styled.div`
      display: flex;
      justify-content: space-evenly;
      align-items: center;
    `;

    const thumb = {
      display: "inline-flex",
      borderRadius: 2,
      marginBottom: 3,
      marginLeft: 1,
      width: 100,
      height: 80,
      padding: 4,
      boxSizing: "border-box",
    };

    const thumbInner = {
      display: "flex",
      minWidth: 0,
      overflow: "hidden",
      display: "flex",
      justifyContent: "space-evenly",
      alignItems: "center",
    };

    const img = {
      display: "block",
      width: "auto",
      height: "100%",
      objectFit: "contain",
    };

    const DeleteButton = styled.button`
      width: 40px;
      height: 17px;
      border-style: hidden;
      text-decoration: underline;
    `;

    //ui 구현
    const ShopImgUpload = ({ setMainFile, MainFile }) => { 등록페이지에서 내려준 props
      const onDelete = e => { 이미지 삭제
        e.preventDefault();
        setMainFile([]);
        setVisible(!Visible);
      };
      const [Visible, setVisible] = useState(false);
      const onCheck = e => {
        e.preventDefault();
        setVisible(!Visible);
      };

      const { getRootProps, getInputProps } = useDropzone({
        accept: {
          "image/png": [], 허용하는 파일 형식
        },
        onDrop: acceptedFiles => {
          setMainFile(
            acceptedFiles.map(file =>
              Object.assign(file, { file에 두번째 인자를 덮어 씌운다.
                preview: URL.createObjectURL(file), 파일을url로 변경해 미리보기를 제공한다.
                original: file, 파일 원본을 백엔드로 전달한다.
              }),
            ),
          );
        },
      });
    original: file
     
     

      //업로드 하려고 선택한 파일의 이미지를 미리보기로 보여준다.
      const thumbs = MainFile.map(file => (
        <div style={thumb} key={file.name}>
          <div style={thumbInner}>
            <img
              src={file.preview}
              style={img}
              onLoad={() => {
                URL.revokeObjectURL(file.preview);
              }}
            />
          </div>
        </div>
      ));

      useEffect(() => {
        return () => MainFile.forEach(file => URL.revokeObjectURL(file.preview));
      }, []);

      return (
        <form action="/save" method="post" encType="multipart/form-data">
          <ShopIntroduceName>가게 대표 사진</ShopIntroduceName>
          <section onDrop={onCheck} onClick={onCheck}>
            <div {...getRootProps()}>
              <input {...getInputProps()} />
              <ShopPhoto></ShopPhoto>
            </div>
            <ShopPhoto>
              <FileInfo>
                {" "}
                {thumbs}
                {MainFile.map(file => (
                  <div key={file.id}>
                    {file.name}
                    <br />
                    {file.size}KB
                  </div>
                ))}
              </FileInfo>

              {Visible ? <DeleteButton onClick={onDelete}>삭제</DeleteButton> : " "} 삼항 연산자
            </ShopPhoto>
          </section>
        </form>
      );
    };

    export default ShopImgUpload;
Designed by Tistory.