[쇼핑몰 사이트 만들기] #2-4. 필터 만들기

ppmyor·2022년 8월 29일
0
post-thumbnail

필터를 다룰 수 있는 함수 부분을 만든다. 필터를 통해 해당 필터에 해당하는 상품들만 노출 될 수 있도록 하는 기능을 구현한다. 필터에는 나라 필터도 있지만, 이 다음에 만들어 낼 가격 필터도 있기 때문에 필터의 부분을 조작할 수 있는 기능을 따로 빼내어 만들어준다.
기능 구현은 아래의 순서대로 진행된다.

목차

  1. Filter State 만들기
  2. handleFilter Function 만들기
  3. getProduct Route를 필터 기능에 맞게 바꾸기

🆕 1. Filter State 만들기

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

//...
function LandingPage() {
  const [Filters, setFilters] = useState({
  continents: [],
  price: [],
  });

  //...
  
  return (
  //...
  )
}
export default LandingPage;

우선 filter에 대한 state를 만들어준다.

✊ 2. handleFilter Function 만들기

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

//...
function LandingPage() {
	//...
	const showFilteredResults = (filters) => {
	  let body = {
	    skip: 0,
 	    limit: Limit,
  	    filters: filters,
	  };

 	 getProducts(body);
 	 setSkip(0);
	};

	const handleFilters = (filters, category) => {
	  const newFilters = { ...Filters };
	  newFilters[category] = filters;
	  showFilteredResults(newFilters);
      setFilters(newFilters);
	};

    return (
      //...
		<CheckBox list={continents} handleFilters={(filters) => handleFilters(filters, "continents")} />;
  )
}
export default LandingPage;

price와 continents 두가지 카테고리의 필터가 있으므로 해당 필터를 적당히 분기처리할 수 있게 handleFilters 매개변수로 category를 넘기도록 하자.
props에서 넘겨받은 체크 된 필터들의 값은 setFilters를 통해 Filters의 올바른 카테고리에 저장해준다. showFilteredResults function을 통해서 필터된 값들, 보여줄 게시글의 갯수 등을 body로 넘겨 getProducts를 통해 DB에서 해당 body에 맞는 상품들을 가지고 올 수 있도록 해준다.

🔥 3. getProduct Route를 필터 기능에 맞게 바꾸기

server/routes/product.js 수정

router.post("/products", (req, res) => {
  let limit = req.body.limit ? parseInt(req.body.limit) : 20;
  let skip = req.body.skip ? parseInt(req.body.skip) : 0;

  let findArgs = {};

  for (let key in req.body.filters) {
    if (req.body.filters[key].length > 0) {
      findArgs[key] = req.body.filters[key];
    }
  }

  Product.find(findArgs)
    .populate("writer")
    .skip(skip)
    .limit(limit)
    .exec((err, productInfo) => {
      if (err) return res.status(400).json({ success: false, err });
      return res.status(200).json({
        success: true,
        productInfo,
        postSize: productInfo.length,
      });
    });
});

원래 구현되어있던 기능 이외에 filter를 추가해준다. .find를 통해서 필터가 지정되었을 경우(length가 0 큰 경우) 해당 filter에 해당하는 상품들만 찾아 json으로 넘겨준다.

➕ 문제 해결

server/models/Product.js 수정

    continents: {
      type: Number,
      default: 1,
    },

기존 보일러 플레이트에 continents 속성이 없었다.. 나라를 선택해서 상품을 등록해도 DB에서는 누락되어있기 때문에 요것을 추가해주자.

➕ 참고

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

profile
유영하는 개발자

0개의 댓글