파일을 저장 할 때 multer 가 필요하다.
https://www.npmjs.com/package/multer
product.js
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 })
destination : 어디에 파일이 저장이 되는지
filename : 어떤 이름으로 저장해줄건지
const express = require('express');
const router = express.Router();
const multer = require('multer');
//=================================
// Product
//=================================
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
cb(null, `${Date.now()}_${file.originalname}`)
}
})
const 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({ seuccess: true, filePath: res.req.file.path, fileName: res.req.file.filename })
// 파일을 어디에, 무슨 이름으로 저장했는지 전달해주는 역할
})
})
module.exports = router;
여행 상품 업로드 페이지에서 확인을 누르면 백엔드에 같이 전달해줘야 한다.
그러기 위해선 이걸 먼저 어딘가에다가 저장을 해야 한다.
이 정보들을 state에다가 저장을 해놓을 것이다.
코드를 입력하세요
이미지를 업로드 하면 state 배열에 이미지가 존재하는 것이다.
이걸 지우는 것을 만들 것이다.
import React, {useState} from 'react'
import Dropzone from 'react-dropzone'
import { Icon } from 'antd';
import axios from 'axios';
function FileUpload() {
const [Images, setImages] = useState([]);
//이미지를 몇개 올릴 수 있게 하기 위해서 배열로 생성
const dropHandler = (files) => {
// 파일을 backend에 전달해줘야 한다.
// 그리고 파일을 전달 할 때 따로 해줘야 하는게 있다.
let formData = new FormData();
const config = {
header: { 'content-type': 'multipart/form-data'}
};
formData.append("file", files[0]);
axios.post('/api/product/image', formData, config).then((response) => {
if (response.data.success){
setImages([...Images, response.data.filePath])
} else {
alert('파일을 저장하는데 실패했습니다.')
}
});
// formData와 config를 넣어주지 않으면은 파일을 보낼 때 에러가 발생하게 된다.
};
const deleteHandler = (image) => { // 이미지 파라미터를 넣어주기
const currentIndex = Images.indexOf(image)
// 클릭하는거에 대한 index를 파악해준다.
let newImages = [...Images]
// 존재하는 이미지를 복사!
newImages.splice(currentIndex, 1)
// 하나만 지울 것이기 때문에 1적어주기.
setImages(newImages)
// 지우고 나서 다시 넣어주기 (새로고침 느낌스~)
}
return (
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Dropzone onDrop={dropHandler}>
{({ getRootProps, getInputProps }) => (
<section>
<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>
</section>
)}
</Dropzone>
<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>
)
}
export default FileUpload
const express = require('express');
const router = express.Router();
const multer = require('multer');
//=================================
// Product
//=================================
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
cb(null, `${Date.now()}_${file.originalname}`)
}
})
const 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({ seuccess: true, filePath: res.req.file.path, fileName: res.req.file.filename })
// 파일을 어디에, 무슨 이름으로 저장했는지 전달해주는 역할
})
})
module.exports = router;
- Product Model 만들기
- Upload File Component 가져오기
- 파일 데이터를 uploadFile 컴포넌트에서 부모 컴포넌트로 업데이트하기
- onSubmit Function 만들기
- 모든 정보를 서버로 보내기
- 보내진 정보를 몽고 DB에 저장하기
- Product Model 만들기
- Upload File Component 가져오기
- 파일 데이터를 uploadFile 컴포넌트에서 부모 컴포넌트로 업데이트 하기
- onSubmit Function 만들기
- 모든 정보를 서버로 보내기
모든 정보를 담고 있는 것을 "submit" 제출을 누르면 Server로 보내줘서 Database에 저장을 해줘야 한다.
그래서 product 모델을 만들어 줄 것이다.
흐음 나 왜 업로드가 안되지?
Product.js
product.js
UploadProductPage.js
auth.js
- 빈 랜딩 페이지 생성
- 몽고 DB에 저장되어 있는 데이터들을 가져오기
- 랜딩 페이지 UI 만들기
- 상품 리스트들을 화면에 보여주기 -> map() methods 사용
router.post('/products', (req, res) => {
// product collection에 들어 있는 모든 상품 정보를 가져오기
Product.find()
.populate("writer")
.exec((err, productInfo) => {
if(err) return res.status(400).json({ success: false, err})
return res.status(200).json({ success: true, productInfo})
})
})
import { Divider } from 'antd';
import React, { useEffect } from 'react'
import { FaCode } from "react-icons/fa";
//백엔드 정보 가져오려고
import axios from "axios";
function LandingPage() {
useEffect(() => {
axios.post('/api/product/products',)
.then(response => {
if(response.data.success){
console.log(response.data)
} else {
alert(" 상품들을 가져오는데 실패 했습니다.")
}
})
}, [])
return (
<div>
Landing Page
</div>
)
}
export default LandingPage
가져오기 성공~ ㅎ_ㅎ
import { Icon, Col, Card, Row } from 'antd';
import React, { useEffect, useState } from 'react'
import { FaCode } from "react-icons/fa";
//백엔드 정보 가져오려고
import axios from "axios";
import Meta from 'antd/lib/card/Meta';
function LandingPage() {
const [Products, setProducts] = useState([])
useEffect(() => {
axios.post('/api/product/products',)
.then(response => {
if(response.data.success){
setProducts(response.data.productInfo)
} else {
alert(" 상품들을 가져오는데 실패 했습니다.")
}
})
}, [])
const renderCards = Products.map((product, index) => {
console.log('product', product)
return <Col lg={6} md={8} xs={24} key={index}>
<Card
cover={<img style={{width:'100%', maxHeight: '150px' }} src={`http://localhost:5000/${product.images[0]}`} />}
>
<Meta
title={product.title}
description={`${product.price}`}
/>
</Card>
</Col>
})
return (
<div style={{ width: '75%', margin: '3rem auto' }}>
<div style={{ textAlign: 'center' }}>
<h2>Let's Travel Anywhere <Icon type="rocket" /></h2>
</div>
{/* Filter */}
{/* Search */}
{/* Cards */}
<Row gutter={[16, 16]}>
{renderCards}
</Row>
<div style={{ display:'flex', justifyContent: 'center' }}>
<button>더보기</button>
</div>
</div>
)
}
export default LandingPage
https://ant.design/components/carousel/
utils > ImageSlider.js
- 더보기 버튼 만들기
- 더보기 버튼을 위한 onClick Function 만들기
- SKIP과 LIMIT을 위한 STATE 만들기
- 더보기 버튼 기능을 사용하기 위해서 getProduct Route를 바꾸기
- Spread Operator를 사용해서 방금 가져온 데이터들을 현재 상품 STATE에 더해주기
- CheckBox 리스트 데이터들을 만들기
- checkbox를 위한 UI 만들기
- onChange Function 만들기
- Checked State를 부모 컴포넌트로 업데이트 하기
이런 리스트를 만들기!
https://ant.design/components/collapse/
- handleFilter Function 만들기
- Filter State 만들기
- getProduct Route를 필터 기능에 맞게 바꾸기
- RadioBox 리스트
- Radiobox를 위한 UI 만들기
- onChange Function 만들기
- Checked State를 부모 컴포넌트로 업데이트 하기