drop-zone은 이미지파일을 drop하는 zone이다.
파일을 드래그하거나 클릭하여 업로드할 수 있다.
설치는 다음과 같다.
npm i drop-zone
import React from 'react'
import Dropzone from 'react-dropzone'
<Dropzone onDrop={onDrop}>
{({getRootProps, getInputProps}) => (
<section>
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
</section>
)}
</Dropzone>
onDrop 으로 함수를 정의할 수 있다.
이 함수로 서버에 이미지 파일을 저장할 것이다.
p태그 부분은 드롭되는 존이므로 원하는대로 ui를 생성해주면 된다.
const onDrop = (files) => {
let formData = new FormData();
formData.append("file", files[0]);
axios
.post("http://localhost:7000/api/product/image", formData)
.then((res) => {
if (res.data.success) {
setImage([...image, res.data.fileName]);
} else {
alert("이미지 업로드 실패");
}
});
setImage로 서버에서 보내주는 이미지파일 정보(파일 이름)를 state에 저장한다.
FormData()로 빈 FormData객체를 생성한다.
그리고 빈 객체에 'file' 키와 files (드롭된 이미지 파일) 밸류를 넣어준다.
그리고 axios로 서버에 post해준다.
client에서 지정해준 경로로 서버에 이미지 파일을 저장한다.
이 때, multer 라이브러리로 이미지 파일을 저장한다.
multer는 diskstorage engine를 사용해 파일을 디스크에 저장할 수 있게 해준다.
설치는 다음과 같다.
npm i multer
이미지 파일을 저장할 폴더를 생성한다.
backend/public
정적파일인 이미지파일을 express가 웹브라우저로 보내줄 수 있게 해준다.
이를 통해 backend/public폴더에 저장된 이미지파일을 웹브라우저에서 불러올 수 있다.app.use('/', express.static("./public"))'http://localhost:포트번호/파일명'
으로 불러올 수 있다.
관련 참고
backend/server/routes/product.js
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "public");
},
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
cb(null, file.fieldname + "-" + uniqueSuffix);
},
});
const upload = multer({ storage: storage }).single("file");
destination의 cb에 두번 째 인자로 이미지 파일을 저장할 폴더를 넣는다.
filename의 uniqueSuffix는 이미지 파일의 고유 이름을 생성해준다.
변수 upload로 multer함수를 저장한다. (multer에는 인자로 storage를 넣어줌.)
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,
});
});
});
client에서 보낸 post 메서드에 response를 보낸다.
서버에 저장해 놓은 정적파일인 이미지파일을 express가 웹브라우저로 보내줄 수 있게 해준다.
이를 통해 로컬 backend/public폴더에 저장된 이미지파일을 웹브라우저에서 불러올 수 있다.app.use('/', express.static("./public"))'http://localhost:포트번호/파일명'
으로 불러올 수 있다.
관련 참고
<div>
{image.map((img, index) => (
<img
key={index}
src={`http://localhost:7000/${img}`}
style={{ width: "13rem", height: "13rem" }}
))}
</div>