DYO 공부하는 블로그

[Re:Life] next 사용하면서 학습한 내용 정리 본문

Project/Re:Life

[Re:Life] next 사용하면서 학습한 내용 정리

DYODa 2025. 9. 29. 19:33

동적 라우팅은 page에서 관리

동적 라우팅을 사용할 때는 layout 레벨에서 사용하면 필요한 parameter를 받아오는 것이 불가능하기 때문에 page에서 관리해야 한다. 정적 라우팅은 상관 없지만, ‘일관성’을 갖추는 게 코드 가독성에 많은 영향을 미치기 때문에 하나로 통일해보자.

server action으로 로그인 시에는 Cookie를 받을 때 직접 관리해줘야 한다.

서버에서 해석을 마치기 때문에 쿠키를 클라이언트로 직접 내려줘야 한다. RCC에서 fetch할 경우 set-cookie가 자동으로 쿠키를 처리해주지만, server action또는 RSC에서 쿠키를 수령해야 하는 경우에는 위와 같이 cookieStore에 직접 쿠키를 삽입해줘야 한다.

  // Set-Cookie 헤더로 자동으로 JSESSIONID가 설정됨
  const setCookieHeaders = res.headers.get("set-cookie");

  if (setCookieHeaders) {
    const jsessionid = setCookieHeaders.match(/JSESSIONID=([^;]+)/)?.[1];
    const cookieStore = await cookies();
    cookieStore.set("JSESSIONID", jsessionid || "", {
      path: "/",
      httpOnly: true,
      secure: process.env.NODE_ENV === "production",
      sameSite: "lax",
      maxAge: 60 * 60 * 24 * 30,
    });
  }

정적 사이트를 생성했을 경우 cookie를 조회할 수 없다.

cookie를 조회하고 사용하기 위해서는 반드시 SSG(정적 사이트 생성) 대신 SSR(서버 사이드 렌더링)로 처리해줘야 한다.

export const dynamic = "force-static"

force-static으로 강제로 정적 사이트를 생성했다면 별다른 오류 메세지 없이 cookie 조회에 undefind를 리턴하므로 주의할 것.

 

병렬 라우팅으로 라우팅 경로를 중첩할 수 있다.

병렬 라우팅 () 을 이용할 경우 라우팅 경로에 영향을 미치지 않도록 설정할 수 있다. 이를 이용해 인증이 필요한 페이지와 인증이 필요 없는 페이지를 구분할 수 있다. 세부 정보와 같은 보안이 필요하면서 부모-자식 관계로 라우팅이 필요한 경우 같은 폴더명을 중첩해 작성할 수 있다.

 

동적 라우팅에서 페이지 자체가 클라이언트 컴포넌트일 경우 use hook을 통해 필요한 값을 추출할 수 있다.

'use client'
import { use, useState, useEffect } from 'react'

interface Movie {
  Title: string
  Plot: string
}

export default function MovieDetails({
  params, // 동적 세그먼트
  searchParams // 쿼리스트링
}: {
  params: Promise<{ movieId: string }>
  searchParams: Promise<{ plot?: 'short' | 'full' }>
}) {
  const { movieId } = use(params)
  const { plot } = use(searchParams)

 

클라이언트 컴포넌트에서 프리로드 사용하기

클라이언트 컴포넌트에서 다음 페이지 로딩을 미리 하도록 처리할 수 있다. routerprefetch를 이용해 라우팅 경로를 지정하면, 다음 페이지는 바로 로드될 수 있는 상태로 대기한다.

'use client'
import { useEffect } from 'react'
import { usePathname } from 'next/navigation'
import { useRouter } from 'next/navigation'
import Link from 'next/link'

// 생략..

export default function Header() {
  const pathname = usePathname()
  const router = useRouter()

  useEffect(() => {
    router.prefetch('/movies')
  }, [router])

  return (
    <header className="flex items-center">
      {/* 생략.. */}
      <button
        className="rounded bg-gray-800 px-2 py-1 text-sm text-white transition-colors hover:bg-gray-700"
        onClick={() => router.push('/movies')}>
        Movies(Push)
      </button>
    </header>
  )
}

서버 컴포넌트에 너무 집착하지 말자

  • 인터렉션 요소, 애니메이션 요소가 늘어나면 클라이언트 컴포넌트가 늘어나는 건 당연하고, input 요소의 label과 같은 요소를 분리한다고 해서 번들 사이즈가 체감 될 정도로 줄어들지는 않는다. 필요에 따라 정적인 요소와 동적인 요소를 구분하고 RSC를 사용할지 RCC를 사용할지 구분하면 된다. 최적화에 정말 집착하고 싶다면 Atomic Design 을 따를 것.

'Project > Re:Life' 카테고리의 다른 글

[Re:Life] 프로젝트 회고  (0) 2025.10.29