Hyebin‘s blog
article thumbnail

Dropzone 라이브러리

https://www.npmjs.com/package/react-dropzone

 

react-dropzone

Simple HTML5 drag-drop zone with React.js. Latest version: 12.0.4, last published: 5 days ago. Start using react-dropzone in your project by running `npm i react-dropzone`. There are 2423 other projects in the npm registry using react-dropzone.

www.npmjs.com

설치 방법

npm install --save react-dropzone

 

사용 방법

import React from 'react'
import Dropzone from 'react-dropzone'

<Dropzone onDrop={acceptedFiles => console.log(acceptedFiles)}>
  {({getRootProps, getInputProps}) => (
    <section>
      <div {...getRootProps()}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
      </div>
    </section>
  )}
</Dropzone>

 

결과화면

 

하지만 파일 선택 시 아무 변화가 일어나지 않는다.

이유는  파일을 받기만 하고 아무런 작업이 없기 때문,  onDrop 시 console.log("") 가 찍히도록 되어있다.

따라서 onDrop이벤트가 일어날 때 무엇을 할 지 함수를 만들어 줘야 한다.

 

 

onDrop 함수처리

파일을 올리면 백엔드에서 저장을 해주고 저장해준 파일의 정보를 프론트에서 가져오는 처리를 해줘야한다.

 <Dropzone onDrop={dropHandler}>
        ...
  </Dropzone>

 

 

multer ? 

Multer는 파일 업로드를 위해 사용되는 multipart/form-data 를 다루기 위한 node.js 의 미들웨어

https://www.npmjs.com/package/multer

 

multer

Middleware for handling `multipart/form-data`.. Latest version: 1.4.4, last published: 2 months ago. Start using multer in your project by running `npm i multer`. There are 3139 other projects in the npm registry using multer.

www.npmjs.com

 

설치

$ npm install --save multer

 

사용 방법

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, '/tmp/my-uploads')
  },
  filename: function (req, file, cb) {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
    cb(null, file.fieldname + '-' + uniqueSuffix)
  }
})

const upload = multer({ storage: storage })

 

server - index.js

app.use("/api/todo", require("./routes/todo"));
app.use("/uploads", express.static("uploads"));

 

server - routes/todo.js

const express = require("express");
const router = express.Router();
const multer = require("multer");
//================================
//             Todo
//================================

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    //destination : 어디에 파일이 저장되는지
    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 res.json({
        success: false,
        err,
      });
    }
    return res.json({
      success: true,
      filePath: res.req.file.path,
      fileName: res.req.file.filename,
    });
  });
});

module.exports = router;

 

client - FileUpload.js

function FileUpload() {
 const dropHandler = (files) => {
    let formData = new FormData();
    const config = {
      header: { "content-type": "multipart/form-data" },
    };
    formData.append("file", files[0]);
    axios.post("/api/todo/image", formData, config).then((res) => {
      if (res.data.success) {
        console.log(res.data);
      } else {
        alert("파일을 저장하는데 실패했습니다.");
      }
    });
    //formData, config를 같이 넣어주지 않으면 file을 보낼 때 에러가 발생한다.
  };
  return (
    <div>
      <Dropzone onDrop={dropHandler}>
        {({ getRootProps, getInputProps }) => (
          <section>
            <FileUploadContents {...getRootProps()}>
              <input {...getInputProps()} />
              <BsPlus style={{ fontSize: "50px" }} /> //ui 아이콘 적용
            </FileUploadContents>
          </section>
        )}
      </Dropzone>

      <div>
      ...
        //보여줄 이미지
    </div>
  );
}

export default FileUpload;

문제 발생 :

사진을 불러와도 계속 실패였다. 

오류를 찾아보니까 'uploads/' 사진 저장 위치를 루트폴더에 만들어 줬지만 계속 루트폴더를 못찾고 server 폴더 안으로 경로를 찾아줘서 발생한것.

강제로 루트폴더에 넣어주면 해결되는 줄 알았는데 static 폴더 지정에서 또 에러가 발생하여 고민하였다.

 

 

문제해결 :

server폴더 안에 넣으니 오류가 해결됐다. 하지만 왜 이렇게 된건지는 좀 더 찾아봐야겠다... 😓

 

profile

Hyebin‘s blog

@hyebin Lee

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그