CakeForU 프로젝트

5. 포트폴리오 페이지

fleur75 2023. 6. 11. 14:29

서비스에 등록된 모든 케이크의 목록을 Infinite Scroll을 통해 스크롤을 내릴 때마다 20개씩 가져와서 보여준다.

 

  const fetchWishList = async (buyerId) => {
    try {
      const response = await axios.get(`/wish/b/${buyerId}`);
      // console.log("user wishlist", response.data);
      if (response.data.result) {
        return response.data.wishlist;
      }
      console.error("Failed to fetch wishlist:", response.data.msg);
      return [];
    } catch (error) {
      console.error("Failed to fetch wishlist:", error);
      return [];
    }
  };

  const fetchMoreData = async () => {
    try {
      const wishlistItemIds = user
        ? await fetchWishList(user.id).then((wishlist) =>
            wishlist.map((item) => item.id)
          )
        : [];

      const response = await axios.get(`/portfolio/list?page=${pageNum}`);
      const newData = response.data;

      // console.log("ids: ", wishlistItemIds);

      const updatedData = newData.map((item) => {
        return {
          ...item,
          filled: wishlistItemIds.includes(item.id),
        };
      });

      // console.log("updatedData = ", updatedData);

      if (newData.length === 0) {
        setHasMoreItems(false);
      } else {
        setPopularCake((prevData) => [...prevData, ...updatedData]);
        setPageNum((prevPageNum) => prevPageNum + 1);
      }
    } catch (error) {
      console.error("Failed to fetch more data:", error);
    }
  };

  useEffect(() => {
    fetchMoreData();
  }, []);

useEffect Hook을 이용하여 페이지가 로딩될 때 최초의 20개를 가져온다.

 

<InfiniteScroll
  dataLength={popularCake.length}
  next={fetchMoreData}
  hasMore={hasMoreItems}
  loader={<h4>Loading...</h4>}
  endMessage={
    <p style={{ textAlign: "center" }}>
      <b>목록의 마지막입니다.</b>
    </p>
  }
>
  <div
    style={{
      display: "grid",
      gridTemplateColumns: "repeat(5, 1fr)",
      gridGap: "21px",
    }}
  >
    {popularCake.map((item) => {
      return (
        <Card
          key={item.imageUrl[0]}
          buyerId={user ? user.id : null}
          portfolioId={item.id}
          sellerId={item.sellerId}
          title={item.detail}
          shape={item.shape}
          sheetTaste={item.sheetTaste}
          creamTaste={item.creamTaste}
          situation={item.situation}
          businessName={item.businessName}
          size={item.size}
          detail={item.detail}
          imgUrl={item.imageUrl}
          color={item.color}
          filled={item.filled}
        />
      );
    })}
  </div>
</InfiniteScroll>

react-infinite-scroll-component 라이브러리를 이용해서 InfiniteScroll 컴포넌트에서 next에 데이터를 가져오는 메서드를 할당함으로써 스크롤을 내릴 때 새로운 아이템을 가져오는 기능을 구현했다.

 

  if (newData.length === 0) {
    setHasMoreItems(false);
  } else {
    setPopularCake((prevData) => [...prevData, ...updatedData]);
    setPageNum((prevPageNum) => prevPageNum + 1);
  }

hasMoreItems의 경우 useState로 관리되는데 스크롤을 내려 아이템을 가져왔을 때 길이가 0이면 모든 데이터를 가져온 것으로 판정하고 상태를 false로 바꿔 InfiniteScroll 컴포넌트에 hasMore로 전달한다.