캐럿마켓 고민한 점

김선은·2023년 11월 2일

일단 여기 모아두고 나중에 정리하기
고민하거나 방법을 선택하고 비교했던 점들이 있던 부분을 메모해두자.

1. 선택된 카테고리를 서버로 보내는 방법

쿼리문자열을 이용해서 보낼건데, 수단에 따른 차이가 있다. useSWR로 코드를 작성했는데, Link를 썼으면 편했겠다 싶었지만 비교해보니 나는 카테고리를 누른다고 새로운 페이지로 옮기고 싶지 않고 캐싱을 할 수 있는 useSWR로 유지해야겠다.

추가로 getServerSideProps에서 리턴한 products을 SWRConfig의 fallback으로 초기데이터 설정을 해놨는데, 카테고리 만든다고 api/products/index에서 리턴값을 바꾼걸 반영하지 않았다. 수정해야겠다. --> 2번으로

<SWRConfig
      value={{
        fallback: {
          "/api/products": {
            ok: true,
            products,
          },
        },
      }}
    >
  1. useSWR
  • useSWR을 이용하면, 데이터를 불러오는 로직과 UI를 분리할 수 있습니다. 즉, 데이터를 불러오는 로직을 따로 분리해서 작성하면, 코드의 가독성이 좋아지고, 유지보수가 용이해집니다.
  • useSWR을 이용하면, 데이터를 캐싱할 수 있습니다. 즉, 같은 데이터를 여러 번 불러올 때, 서버에 요청을 보내지 않고, 캐시된 데이터를 사용할 수 있습니다. 이는 네트워크 비용을 줄이고, 애플리케이션의 성능을 향상시킵니다.
  1. Link
  • Link를 이용하면, 브라우저의 주소창에 쿼리 문자열이 표시됩니다. 이는 사용자가 현재 어떤 페이지를 보고 있는지 알 수 있게 해주고, 사용자가 즐겨찾기나 공유하기를 할 때도 유용합니다.
  • Link를 이용하면, 브라우저의 뒤로가기, 앞으로가기 버튼을 이용해서 페이지를 이동할 수 있습니다. 이는 사용자 경험을 향상시키는 데 도움이 됩니다.

따라서, useSWRLink를 이용해서 쿼리 문자열을 보내는 방법은 각각의 상황에 따라 선택해야 합니다.
만약, 데이터를 불러오는 로직과 UI를 분리하고, 데이터를 캐싱하고 싶다면 useSWR을 이용하는 것이 좋습니다. 반면에, 브라우저의 주소창에 쿼리 문자열을 표시하고, 브라우저의 뒤로가기, 앞으로가기 버튼을 이용해서 페이지를 이동하고 싶다면 Link를 이용하는 것이 좋습니다.

SSR 적용 확인하기

getServerSideProps로 props를 리턴하고 SWRConfigfallback을 이용해서 데이터를 페칭하기 전부터 전체 상품을 보여주려는 것이 목표이다.

카테고리를 추가하면서 api 엔드포인트에서 리턴하는 이름이 다양해졌고 useSWR과 같이 사용하면서 보니 ssr 적용이 안되는 것 같았다. 아직 SWRconfig가 익숙하지 않아서 헤맸지만 다른거 다 싹 빼고 props만으로 데이터가 보이는지 확인하다보니 SSR가 성공적으로 된다! 로딩이 없다!

  1. getServerSideProps에서 리턴하기
export async function getServerSideProps() {
  const Allproducts = await client.item.findMany({});
  return {
    props: {
      Allproducts: JSON.parse(JSON.stringify(Allproducts)),
    },
  };
}

export default Page;

  1. SWRConfig의 fallback에 담기
const Page: NextPage<{ Allproducts: any }> = ({ Allproducts }) => {
  return (
    <SWRConfig
      value={{
        fallback: {
          "/api/products": {
            ok: true,
            Allproducts,
          },
        },
      }}
    >
      <Home Allproducts={Allproducts} />
    </SWRConfig>
  );
};

  1. 사용할 컴포넌트에서 props로 받아서 꺼내쓰기!
    참고로 {}로 감싸는 것은 ES6에서 도입된 객체 분해 할당의 구문.
export function Home({ Allproducts }) {
  return(
  	{Allproducts?.map // ... 생략
  )
}

아직 코드를 다 수정한게 아니어서 두는용

export interface ProductWithCount extends Item {
  _count: {
    favs: number;
  };
}

interface AllProductsResponse {
  Allproducts: ProductWithCount[];
}

export function Home({ Allproducts }: AllProductsResponse) {
  return (
    <Layout title="Home" hasTabBar>
      <div className="grid sm:grid-cols-2 gap-2 border-t pt-8">
        {!Allproducts ? "Loading..." : ""}
        <>
          {Allproducts?.map((product: ProductWithCount) => (
            <HomeItem
              id={product.id}
              key={product.id}
              title={product.name}
              price={product.price.toLocaleString("ko-KR")}
              hearts={product._count?.favs}
              imageUri={product.image}
            />
          ))}
        </>
      </div>
    </Layout>
  );
}

const Page: NextPage<{ Allproducts: any }> = ({ Allproducts }) => {
  return (
    <SWRConfig
      value={{
        fallback: {
          "/api/products": {
            ok: true,
            Allproducts,
          },
        },
      }}
    >
      <Home Allproducts={Allproducts} />
    </SWRConfig>
  );
};

export async function getServerSideProps() {
  const Allproducts = await client.item.findMany({
    include: {
      _count: {
        select: {
          favs: true,
        },
      },
    },
    orderBy: {
      createAt: "desc",
    },
  });
  return {
    props: {
      Allproducts: JSON.parse(JSON.stringify(Allproducts)),
    },
  };
}

export default Page;
profile
기록은 기억이 된다

0개의 댓글