-
OnlineShop 만들기 - 9) Product Detail Page 만들기2 (Add to cart 기능 만들기)NODE.JS 2021. 5. 16. 15:49
이번에는 상품 디테일 페이지에서 장바구니에 상품을 담을 수 있는 add to cart 기능을 만든다.
cart는 로그인된 유저에 한해서 하나의 장바구니 만을 가질 수 있다.
(user 모델에 cart가 존재(카트가 사용자에게 속하므로))
우리는 이를 구현할 때 리덕스를 이용해서 사용자 정보를 관리하는 식으로 진행한다.
또한 장바구니에 담기를 클릭했을때 이미 장바구니에 존재하는 상품이라면
장바구니 아이콘 위의 수는 변함이없지만 장바구니에 들어가면 상품의 갯수가 증가하는 식으로 진행한다.
user모델에 cart 정보를 넣어주자.
추가로 나중에 사용할 history 정보도 넣어주자.(본 제품들 기록할 것)
const userSchema = mongoose.Schema({ name: { type: String, maxlength: 50 }, email: { type: String, trim: true, unique: 1 }, password: { type: String, minglength: 5 }, lastname: { type: String, maxlength: 50 }, role: { type: Number, default: 0 }, cart: { type: Array, default: [] }, history: { type: Array, default: [] }, image: String, token: { type: String, }, tokenExp: { type: Number } })
우선 product info.js에 카트에 넣는 onClick 기능을 만들자.
여기서 props로 받아온 addTocart 함수를 사용해서 장바구니 안에 넣는기능을 하도록 만들것이다.
const addToCarthandler = () => { props.addToCart(props.detail._id) } <Button size="large" shape="round" type="danger" onClick={addToCarthandler} > Add to Cart </Button>
부모페이지인 detailProductPage로 가서 addtoCart 함수를 만들고 prop으로 보내준다.
여기서 redux -dispatch를 통해서 정보를 보내준다.
import { addToCart } from '../../../_actions/user_actions'; import { useDispatch } from 'react-redux'; const addToCartHandler = (productId) => {//상품 아이디를 받으면 dispatch(addToCart(productId)) } <Col lg={12} xs={24}> <ProductInfo addToCart = {addToCartHandler} detail = {Product}/> </Col>
addToCart라는 액션을 user_actions안에 만들어 줄것이다.
import { LOGIN_USER, REGISTER_USER, AUTH_USER, LOGOUT_USER, ADD_TO_CART_USER } from './types'; export function addToCart(_id){ const request = axios.get(`${USER_SERVER}/addToCart?productId = ${_id}`) .then(response => response.data); return { type: ADD_TO_CART_USER, payload: request } }
types.js에도 추가해준다.
export const ADD_TO_CART_USER = 'add_to_cart_user';
리덕스를 사용하기 위해서 reducer_user에도 넣어준다.
import { LOGIN_USER, REGISTER_USER, AUTH_USER, LOGOUT_USER, ADD_TO_CART_USER } from '../_actions/types'; case ADD_TO_CART_USER : return {... state, userData:{ ...state.userData, cart:action.payload //카트 정보도 추가로 넣어준다. }}
순서는 info에서 add to cart 누르면, 디테일 페이지의 add to cart로 이동, 그다음 user_actions로 가서 해당 기능 찾고 route로 가서 정보 가져오는 것이다.
user_actions에서 axios를 날려줬으니
이제 user router로 가서 addtocart부분을 만들어주자.
router.get('/addToCart', auth, (req, res) => { User.findOne({ _id: req.user._id }, (err, userInfo) => {//middleware의 auth에서 user_id받아온다. let duplicate = false;//카트에 이미 동일 제품이 있는지 확인 console.log(userInfo) userInfo.cart.forEach((item) => { if (item.id == req.query.productId) { duplicate = true; } }) if (duplicate) {//이미 해당제품이 있다면 갯수만 늘린다. User.findOneAndUpdate( { _id: req.user._id, "cart.id": req.query.productId }, { $inc: { "cart.$.quantity": 1 } },// increase number 1 { new: true },//업데이트 한 다음에 document를 되돌려 주기 위해서 (결과를 데이터 베이스에 바로 반영) (err, userInfo) => { if (err) return res.json({ success: false, err }); res.status(200).json(userInfo.cart) } ) } else {//해당제품이 없다면 User.findOneAndUpdate( { _id: req.user._id }, { $push: {//카트를 추가한다. cart: { id: req.query.productId, quantity: 1,//새로 추가되는 것이니까 date: Date.now() } } }, { new: true },//db에 바로반영 (err, userInfo) => { if (err) return res.json({ success: false, err }); res.status(200).json(userInfo.cart) } ) } }) });
route에서 실행하고 돌아온 정보를 useractions에서 받아서 reduce에 보내고 reducer에서 state를 저장한다.
화면창의 redux state를 확인하면 카트가 들어온 것을 확인할 수 있다.
'NODE.JS' 카테고리의 다른 글
OnlineShop 만들기 - 11) Cart Page 만들기 2 (cart 페이지 템플릿 만들기) (0) 2021.05.16 OnlineShop 만들기 - 10) Cart Page 만들기 1 (cart정보 가져오기) (0) 2021.05.16 OnlineShop 만들기 - 8) Product Detail Page 만들기1 (상품 이미지, 상품 설명란 만들기) (0) 2021.05.15 OnlineShop 만들기 - 7) Landing Page 만들기 4(Search feature 만들기) (0) 2021.05.15 OnlineShop 만들기 - 6) Landing Page 만들기 3(check 필터링, price 필터링 만들기) (0) 2021.05.15