230519.til

Universe·2023년 5월 19일
0
post-custom-banner

레아이웃 컴포넌트 심화과정

심화과정이라고 하면 조금 거창하긴 하지만
여러가지 가능성을 두고 연습을 해봐야 실력이 늘기 때문에
심화과정이라고 하겠다.

추가적으로 앞으로의 프로젝트는 모두 타입스크립트로 진행하려고 한다.
타입스크립트만 지원하는 prisma 같은 ORM 도 있고,
정적 타이핑의 장점을 살려서 개발하는 버릇을 들이는 편이 아무래도 좋다는 생각이 든다.

구현물

스타일링은 따로 진행하지 않고 tailwind 를 사용해 가볍게
margin, padding, border 정도만 넣어주었다.
tailwind 를 연습하는 것도 정말 재밌는데,
익숙해지면 많이 쓰던 styled-components 이상으로 편할 것 같다.
현재 버전의 Next js 에서 서버 컴포넌트에서 js-in-css 를 사용하기 까다롭다는게
많은 개발자들이 tailwind 를 사용하는 이유라고 하지만
그 이외에도 컴포넌트 작명 같은 아주아주 어려운 작업을 하지 않아도 된다는 점에서
개인적으로 많이 좋아하게 될 것 같은 스타일링 도구다.

디렉토리


디렉토리는 위와같이 진행 했다.
dynamic route 폴더 명에 slug, 혹은 id 라는 키워드를 사용하라고
공식 문서에 나와있지만 개인적으로는 직접 작명하는 것이 조금 더 알기 편한 것 같다.

코드

import React from "react";

export default function ProductsLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <section>
      <nav className="flex justify-start items-center px-10 py-5 text-2xl gap-16">
        <a href="/products/man">Man</a>
        <a href="/products/Woman">Woman</a>
      </nav>
      {children}
    </section>
  );
}

products 페이지의 layout 컴포넌트.
products 페이지에서는 남자 혹은 여자라는 링크로 갈 수 있는 navbar 를 만들었다.
Next js 에서는 Link 태그를 사용하는 것이 좋다.
a 태그를 사용하면 링크를 클릭할 때마다 새로운 HTTP 요청을 서버로 하게 되므로
페이지 로딩시간이 늘어난다.
반면에, Link 태그는 클라이언트 사이드 라우팅을 지원해서 필요한 데이터만 가져와
페이지를 즉시로딩 할 수 있다.
React 에서 a 태그대신 react-router-dom 의 Link 태그를 사용하는 것과
비슷한 이유.

type Props = {
  params: {
    slug: string;
  };
};

export default function ItemPage({ params }: Props) {
  return <h1>{params.slug}Page</h1>;
}

export function generateStaticParams() {
  const gender = ["man", "woman"];
  return gender.map((e) => ({ slug: e }));
}

서버 컴포넌트에서 generateStaticParams 함수를 사용하면
미리 페이지를 만들어놓을 수 있다.

// layout.tsx
import Link from "next/link";
import React from "react";

type Props = {
  children: React.ReactNode;
  params: { slug: string };
};

export default function GenderLayout({ children, params }: Props) {
  return (
    <section>
      <nav className="flex justify-start items-center px-10 py-5 text-1xl gap-16">
        <Link href={`/products/${params.slug}/shirt`}>Shirt</Link>
        <Link href={`/products/${params.slug}/pants`}>Pants</Link>
        <Link href={`/products/${params.slug}/skirt`}>Skirt</Link>
        <Link href={`/products/${params.slug}/shoes`}>Shoes</Link>
      </nav>
      {children}
    </section>
  );
}


//[category]/page.tsx
"use client";
import React from "react";

type Props = {
  params: {
    slug: string;
    category: string;
  };
};

type CategoryData = Record<string, number[]>;

export default function CategoryPage({ params }: Props) {
  const data: CategoryData = {
    shirt: [1, 2, 3],
    pants: [4, 5, 6],
    skirt: [7, 8, 9],
    shoes: [10, 11, 12],
  };
  return (
    <div className="grid grid-cols-3 gap-4 px-10 py-5">
      {data[params.category]?.map((e, i) => (
        <div key={i} className="border-2 border-sky-600 h-60">
          {e}
        </div>
      ))}
    </div>
  );
}

layout 컴포넌트로 shirt, pants, skirt, shoes 의 카테고리를
navbar 로 만들어 주었다. 해당 카테고리는 세부 모든 페이지에서 볼 수 있어야 한다.

category 데이터도 api fetch로 받아와서 보여주는 기능도 만들어보면 좋을 것 같지만
일단 편의상 data 라는 임의의 더미 데이터로 바인딩을 해줬다.
데이터는 유동적으로 바뀔 수 있으니까 클라이언트 컴포넌트로 만들어 준 모습.

여담

Next js는 알면 알수록 신기하고 재밌는 기능이 많다.
SSR, CSR, SSG 같은 렌더링 솔루션에 대해서도 조금 더 깊게 알 수 있고,
어떤 경우에 어떤 방식을 사용해야 하는지에 대해서도 고민해볼 수 있는 기회가 되는 것 같다.

profile
Always, we are friend 🧡
post-custom-banner

0개의 댓글