[쇼핑몰 사이트 만들기] #3-1. 상품의 상세 정보를 데이터베이스에서 가져오기

ppmyor·2022년 9월 14일
0
post-thumbnail

상품의 상세 페이지 구현을 위해 DB에서 상세 정보를 가져오는 과정을 거쳐야한다. 구현은 다음 순서대로 진행된다.✊

목차

  1. 빈 상품 상세 페이지 만들기
  2. Product detail page를 위한 Route 만들기
  3. product 정보를 DB에서 가져오기

🆕 1. 빈 상품 상세 페이지 만들기

상품 상세페이지의 url은 product url 뒤에 각각의 상품마다 부여될 유니크 아이디를 붙여 구성된다.
예를 들면 localhost:3000/product/123456abcdef 이런 식이다.

src/components/views/LandingPage/LandingPage.js 수정

function LandingPage() {
  //...
  const renderCards = Products.map((product, index) => {
    return (
      <Col lg={6} md={8} xs={24} key={index}>
        <Card
          cover={
            <a href={`/product/${product._id}`}>
              <ImageSlider images={product.images} />
            </a>
          }
        >
          <Meta title={product.title} description={`$${product.price}`} />
        </Card>
      </Col>
    );
  });

return (
//...
      <Row gutter={[16, 16]}>{renderCards}</Row>
	);
}

export default LandingPage;

디자인은 ant Design의 Card를 이용하고, 유니크 아이디는 product의 id로 부여된다. 해당 Card를 누르면 유니크 아이디와 일치하는 상품의 상세페이지로 이동하는 식이다.

🆕 2. Product detail page를 위한 Route 만들기

위의 단계는 product._id가 붙은 링크로 이동하는 기능만 구현했을 뿐이고, 해당 유니크 아이디가 부여된 링크로 만들어진 페이지가 없기 때문에 오류가 난다. 따라서 path에 맞는 컴포넌트를 생성해주는 과정이 필요하다.

src/components/App.js 수정

import DetailProductPage from "./views/DetailProductPage/DetailProductPage";

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <NavBar />
        <Switch>
        // ..
          <Route exact path="/product/:productId" component={Auth(DetailProductPage, null)} />
        </Switch>
      </div>
      <Footer />
    </Suspense>
  );
}

유니크 아이디는 다 다르기 때문에 ":"를 표기 한다. :productId 를 통해서 path의 컴포넌트를 생성 후 접근하는 식이다.

src/components/views/DetailProductPage/DetailProductPage.js 생성

import React from "react";

function DetailProductPage() {
  return <div>DetailProductPage</div>;
}

export default DetailProductPage;

그리고 상품의 상세 사항들을 띄워줄 상품 상세 페이지 컴포넌트를 생성해준다.

🔥 3. product 정보를 DB에서 가져오기

해당 상품에 대한 모든 정보들은 유니크 아이디를 이용해서 가져온다. 유니크 아이디와 일치하는 모든 정보들(타이틀, 이미지, 가격, 설명, 팔린 양,view 수 등)을 달라고 DB에 요청한다.

server/routes/product.js 수정

router.get("/products_by_id", (req, res) => {
  //productId를 이용해서 DB에서 productId와 같은 상품의 정보를 가져온다.
  let type = req.query.type;
  let productId = req.query.id;

  Product.find({ _id: productId })
    .populate("writer")
    .exec((err, product) => {
      if (err) return res.status(400).send(err);
      return res.status(200).send({ success: true, product });
    });
});

productId에 대한 id는 쿼리스트링이기 때문에 req.query.~~ 의 형태로 받아주고 Product의 _id 중 ProductId와 일치하는 값을 find를 통해 찾아준다.

src/components/views/DetailProductPage/DetailProductPage.js 수정

import axios from "axios";
import React, { useEffect } from "react";

function DetailProductPage(props) {
  const productId = props.match.params.productId;
  useEffect(() => {
    axios.get(`/api/product/products_by_id?id=${productId}&type=single`).then((response) => {
      if (response.data.success) {
        console.log(response.data);
      } else {
        alert("상세 정보 가져오기를 실패했습니다.");
      }
    });
  }, []);
  return <div>DetailProductPage</div>;
}

export default DetailProductPage;

get으로 productId를 보낸 뒤 일치하는 값이 있다면 해당 상품의 response를 우선 console.log 로 확인하는 형태로 구현해두었다. 여기서 props.match.params.productId는 router에서 상세페이지로 이동할 때 path를 :productId 의 형태로 넘겨주었는데 이 부분을 가져온다.

➕ 참고

따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기 를 공부하며 작성한 글입니다.

profile
유영하는 개발자

0개의 댓글