[Node/React] 쇼핑몰 사이트 만들기 - 02 파일 업로드 컴포넌트 만들기

JS·2023년 2월 16일
0
post-thumbnail

2-1. Utils 폴더 안에 파일 업로드 파일 만들기

utils/FileUpload.js

2-2. Drop-zone 라이브러리 다운받기

구글에 react-dropzone npm 검색 후 사이트에 들어가서 dropzone 사용법 추출
npm install react-dropzone --save

2-3. File 업로드 컴포넌트를 위한 UI 생성

import React, { useState } from 'react'
import Dropzone from 'react-dropzone'
import { Icon } from 'antd';
import axios from 'axios';

function FileUpload() {
    return (
        <div style={{ display: 'flex', justifyContent: 'space-between' }}>
            <Dropzone onDrop={dropHandler}>
                {({ getRootProps, getInputProps }) => (
                    <div
                        style={{
                            width: 300, height: 240, 
                            border: '1px solid lightgray', 
                            display: 'flex', alignItems: 'center', 
                            justifyContent: 'center'
                        }}
                        {...getRootProps()}>
                        <input {...getInputProps()} />
                        <Icon type="plus" style={{ fontSize: '3rem' }} />
                    </div>
                )}
            </Dropzone>
        </div>
    )
}
export default FileUpload

2-4. onDrop Function 생성

Dropzone을 이용해서 파일을 올린다 -> 그 파일을 백엔드(노드서버)에 전달
-> 보낸 파일을 저장 하기 위해 Multer라는 라이브러리에 파일을 저장
-> 파일이 저장된 위치나 이름 같은 것들을 프론트엔드에 다시 전달

 const dropHandler = (files) => {
   
    let formData = new FormData();
    const config = {
      header: { "content-type": "multipart/fomr-data" },
    };
    formData.append("file", files[0]);

    axios.post("/api/product/image", formData, config).then((response) => {
      if (response.data.success) {
        setImages([...Images, response.data.filePath]);
        props.refreshFunction([...Images, response.data.filePath]);
      } else {
        alert("파일을 저장하는데 실패했습니다.");
      }
    });
  };

multipart/form-data는 파일 업로드 즉, 이미지나 영상같은 파일을 제어하는 사용한다

2-4-1. multer를 이용하여 이미지 저장

Multer는 multipart/form-data를 다루기 위한 node.js의 미들웨어로
파일 자체를 전송하려 할 때 생각 대로 전송 되지 않을 경우가 있다.
이런 상황에서 파일을 온전히 전송하기 위해 form 태그의 encType속성을
multipart/form-data로 바꿔줘야 한다.

Multer -> npm install multer --save

// product.js/ 


var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "uploads/");
  },
  filename: function (req, file, cb) {
    cb(null, `${Date.now()}_${file.originalname}`);
  },
});

var upload = multer({ storage: storage }).single("file");


router.post("/image", (req, res) => {
  //가져온 이미지를 저장을 해주면 된다.
  upload(req, res, (err) => {
    if (err) {
      return req.json({ success: false, err });
    }
    return res.json({
      success: true,
      filePath: res.req.file.path,
      fileName: res.req.file.filename,
    });
  });
});

2-5. onDelete Function 생성

이미지를 2개 이상 넣었을 때 삭제하고 싶은 이미지 클릭 시
삭제 가능하게 구현
array[] 안에 넣어놓은 image를 삭제하기 위함

    const deleteHandler = (image) => {
        const currentIndex = Images.indexOf(image);
        let newImages = [...Images]
        newImages.splice(currentIndex, 1)
        setImages(newImages)
        props.refreshFunction(newImages)
    }
   <div
        style={{
          display: "flex",
          width: "350px",
          height: "240px",
          overflowX: "scroll",
        }}
      >
        {Images.map((image, index) => (
          <div onClick={() 
   			=> deleteHandler(image)} key={index}>
            <img
              style={{ minWidth: "300px", 
        width: "300px", height: "240px" }}
              src={`http://localhost:5000/${image}`}
            />
          </div>
        ))}
      </div>
    </div>
profile
신입 FE 개발자

0개의 댓글