Next.js의 라우팅

김예린·2024년 3월 14일
1

Next 프로젝트 시작

npx create-next-app@latest


src>app 아래에 layout.tsx, page.tsx 기본 파일이 있다.
이 기본 layout.tsx파일은 루트레이아웃이다!
이 기본 page.tsx파일은 로컬호스트3000으로들어가면 나오는 메인 화면이다!

app밑에 폴더를 만들고 그 폴더 안에 page.tsx를 놓으면 그 폴더로 라우팅이 자동으로 된다.
만약 app>todolist>page.tsx 라면
http://localhost:3000/todolist
이렇게...todolist안의 page.tsx가 읽혀진다.

dynamic routing

리액트에서 react-router-dom을 사용할 때는 특정 경로가 다이나믹한 파라미터에 의해 계속 변할때

<Route path="/products/:id" element={} />

이런 식으로 했었다
Next에서는?????????????????
폴더 이름을 대괄호로 감싸주기만 하면된다.
app>posts/[id]/page.tsx
이렇게하면 /posts/1, /posts/2 이렇게 다이나믹 라우팅이 가능하다.

// app>test>[id]>page.tsx
import React from "react";

const TestDetailPage = ({
  params,
}: {
  params: {
    id: string;
  };
}) => {
  return <div>Detail 페이지 : {params.id}</div>;
};

export default TestDetailPage;

id를 파라미터로 받아와서 디테일 페이지를 만드는 코드.

route groups

app 아래에 폴더를 만들면 일단 자동으로 라우팅에 포함된다.
근데 라우팅에 포함시키고 싶지 않을수도 있으니까...
그럴때는 폴더이름을 ()이걸로 감싼다.
src>app>(admin)>about>page.tsx
폴더를 이렇게 지정했으면,
localhost:3000/about 으로 라우팅된다.
admin이 라우팅 path에 포함되지 않는다.

special한 파일들

넥스트에서는 라우팅을 폴더기반으로 구현한다.
이 과정에서 어떤 라우트에 대한 "특정 처리"를 위해 생성되는 여러 special files가 존재한다.

특정 처리란?

  • 특정 경로 하위에 있는 routing은 모두 공통 layout을 적용하고 싶다거나
  • 특정 컴포넌트가 로딩중일 때, 오류가 발생했을 때 보여주고 싶은 UI가 있다거나

공통 layout???

layout 파일은 어떤 segment와 그의 자식 노드에 있는 요소들이 공통적으로 적용받게 할 UI를 정의한다.
자식 노드에 있는 요소들이 공통 적용을 받아야하기 때문에 반드시 childrenprop이 존재 해야한다!!
동일 레이아웃 안에서 다른 경로로 왔다갔다 해도 리렌더링이 일어나지 않기때문에 헤더, 푸터, 사이드바 등에 쓰면 좋겠다~ => template과의 차이점

react-router-dom 이용했을 때

createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<Root />}>
      <Route path="contact" element={<Contact />} />
      <Route
        path="dashboard"
        element={<Dashboard />}
        loader={({ request }) =>
          fetch("/api/dashboard.json", {
            signal: request.signal,
          })
        }
      />
      <Route element={<AuthLayout />}>
        <Route
          path="login"
          element={<Login />}
          loader={redirectIfUser}
        />
        <Route path="logout" action={logoutUser} />
      </Route>
    </Route>
  )
);

Next.js 사용했을 때는
내가 특정 레이아웃을 적용시키고 싶은 곳(폴더)아래 layout.tsx를 만든다.(children도 반드시 포함시킴)

export default function DashboardLayout({
  children, // will be a page or nested layout
}: {
  children: React.ReactNode
}) {
  return (
    <section>
      {/* Include shared UI here e.g. a header or sidebar */}
      <nav></nav>
 
      {children}
    </section>
  )
}

그러면 내가 적용하고싶은 곳에 레이아웃이 생성된다!

metadata와 SEO


넥스트는 향상된 SEO를 제공하기 위해서 기존에 우리가 html head부분에 삽입했던 정보들을 metadata라는 객체형태로 지원한다.

  • 리액트에서의 메타데이터

metadata라는 객체 형태로 제공되기 때문에 넥스트에서는 Config-based Metadata를 활용할 수 있다.(두가지 버전)
1. static
내가 원하는 page.tsx 또는 layout.tsx 어디든지

export const metadata: Metadata = {
	title: "Sparta Next App",
	description: "This is awesome Website",
}

를 삽입해놓으면 적용 된다.
단,

  • metadata in page.tsx : 해당 page.tsx 컴포넌트에만 적용
  • metadata in layout.tsx : 해당 layout의 하위 요소에 모두 적용
  1. dynamic
    다이나믹 라우트를 가지고 있는 라우트에서 동적으로 변경되는 파라미터를 기반으로 metadata를 변경하고 싶을때는 generateMetadata function을 사용하면 된다.
import React from "react";

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

export function generateMetadata({ params }: Props) {
  return {
    title: `Detail 페이지 : ${params.id}`,
    description: `Detail 페이지 : ${params.id}`,
  };
}

const TestDetailPage = ({ params }: Props) => {
  return <div>Detail 페이지 : {params.id}</div>;
};

export default TestDetailPage;
  • Link 태그는 prefetching을 지원함
    • Next.js의 <Link> 컴포넌트는 뷰포트에 링크가 나타나는 순간 해당 페이지의 코드와 데이터를 미리 가져오는 프리페칭 기능을 지원합니다. 사용자가 링크를 클릭하기 전에 데이터를 미리 로드함으로써 사용자가 링크를 클릭했을 때 거의 즉시 페이지를 볼 수 있게 합니다.
  • Link 태그는 route 사이에 client-side navigation을 지원함
    • Link 컴포넌트는 브라우저가 새 페이지를 로드하기 위해 서버에 요청을 보내는 대신 클라이언트 측에서 페이지를 바꾸어 주기 때문에 페이지 전환 시 매우 빠른 사용자 경험을 제공한다.
      페이지의 HTML을 서버에서 다시 가져올 필요 없이 필요한 json데이터만 서버로부터 가져와서 클라이언트에서 페이지를 재구성하여 렌더링.

Router(useRouter)

useRouter를 사용할 때는 항상 코드 최상단에 "use client"를 삽입해야 한다!!!

대부분 onClick 같은 이벤트 핸들러에서 사용됨
클릭 후 로직의 순서에 따라 실행하므로 즉시 이동이 아니다

"use client";

import { useRouter } from "next/navigation";

export default function Test () {
	const router = useRouter();
	
	const handleButtonClick = () => {
		로직1();
		로직2();
		
		...
		
		router.push("/new_location");
	}

	return <button onClick={handleButtonClick}>클릭!</button>
}
profile
아자아자

2개의 댓글

comment-user-thumbnail
2024년 3월 15일

TIL의 신....

답글 달기
comment-user-thumbnail
2024년 3월 15일

제가 찾던 넥스트 정보 여기에 있었네요

답글 달기