230519.til

Universe·2023년 5월 19일
0

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

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

추가적으로 앞으로의 프로젝트는 모두 타입스크립트로 진행하려고 한다.
타입스크립트만 지원하는 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 🧡

0개의 댓글