TIL 24. 01. 12

중고 물품 목록은 사용자에게 빠른 속도로 보여지기를 원한다. 필터가 있기는 하지만 실시간으로 변화하는 데이터가 아니기 때문에 SSG로 pre-rendering 하고자 했다.react query의 prefetchQuery 함수를 사용하여 애플리케이션에서 데이터를 미리 가져온다.

TODO

  • 중고 물품 목록 표시
  • 카테고리(견종 사이즈, 물품 종류)와 물품 상태(판매중, 판매완료)로 필터링
  • 키워드 검색
  • 정렬 (최신순, 인기순, 저가순, 고가순) - To Be Determined
<UsedGoods> 				// 페이지 컴포넌트 path="/used-goods"
  <UsedGoodsListFilter />	// 카테고리, 물품 상태 필터
  <UsedGoodsList list={list}> 			// 중고 물품 목록
    <UsedGoodsItem item={item}/> 		// 중고 물품 아이템
    <UsedGoodsItem />
  </UsedGoodsList>
</UsedGoods>
  • UsedGoods: 페이지(“/used-goods”). 데이터 Fetching하여 전달
    • UsedGoodsListFilter: 카테고리, 물품 상태로 필터링 (query string)
    • UsedGoodsList: 중고 물품 목록 표시
      • UsedGoodsItem: 중고 물품 아이템

UsedGoodsListFilter에서 URL 변경 (server action 이용하여 redirect) ➡ UsedGoods에서 params를 기준으로 data fetching ➡ API 응답 파싱하여 UsedGoodsList로 전달

구현

// app/used-goods/page.tsx

import { UsedGoodsListFilter, UsedGoodsList } from './_components';
import { HydrationBoundary, QueryClient, dehydrate } from '@tanstack/react-query';
import { supabase } from '@/shared/supabase/supabase';
import { QueryData } from '@supabase/supabase-js';

const usedItemsWithCategoryAndCountQuery = supabase
  .from('used_item')
  .select(
    `id, created_at, title, price, address, sold_out, photo_url, main_category (name), sub_category (name), chat_list ( count ), used_item_wish ( count )`
  );
export type UsedItemsWithCategoryAndCount = QueryData<typeof usedItemsWithCategoryAndCountQuery>;
export const getUsedGooddsKey = 'used-goods';

export const getUsedGoods = async () => {
  const { data } = await usedItemsWithCategoryAndCountQuery;
  return data ?? [];
};

type SearchParams = { searchParams?: { [key: string]: string | undefined } };

const UsedGoods = async ({ searchParams }: SearchParams) => {
  const { main, sub, search, page, orderBy } = searchParams || {};

  const queryClient = new QueryClient();
  await queryClient.prefetchQuery({
    queryKey: [getUsedGooddsKey],
    queryFn: getUsedGoods,
    staleTime: 60 * 1000
  });

  return (
    <div>
      <h2>중고 물품 리스트</h2>
      <UsedGoodsListFilter />
      <HydrationBoundary state={dehydrate(queryClient)}>
        <UsedGoodsList />
      </HydrationBoundary>
    </div>
  );
};

export default UsedGoods;
// app/used-goods/_components/UsedGoodsList.tsx

'use client';

import { useQuery } from '@tanstack/react-query';
import { getUsedGoods } from '../page';
import UsedGoodsItem from './UsedGoodsItem';

const UsedGoodsList = () => {
  const { data } = useQuery({ queryKey: ['used-goods'], queryFn: getUsedGoods });

  return <div>{data?.map((goods) => <UsedGoodsItem key={goods.id} goods={goods} />)}</div>;
};

export default UsedGoodsList;

카테고리:

업데이트:

댓글남기기