JiSoo's Devlog

[Next.js] Routing 본문

Frontend/Next.js

[Next.js] Routing

지숭숭숭 2024. 8. 4. 22:28

Next.js는 app 폴더 안의 page라는 파일을 참조한다

컴포넌트 이름은 중요하지 않지만 그 컴포넌트가 default 컴포넌트로 export 되어야 한다는 게 중요!

React를 따로 import 하지 않아도 된다

 

 

Defining Routes

react-router는 기본적인 리액트 애플리케이션에서 라우팅 하는 방법

url을 지정하고 컴포넌트 render를 요청

 

Next.js는 폴더를 사용해 경로를 정의하는 파일 시스템 기반 라우터를 사용한다

중첩된 경로를 만들려면 폴더를 중첩하면 된다

 

1. 파일 시스템을 통해 경로를 표시

2. page파일을 해당 디렉토리 안에 생성

 

실제로 보여지는 페이지를 만들려면 page.tsx나 page.jsx 파일을 폴더 내부에 생성해야 한다

직접적인 page파일이 없는 폴더는 실제 페이지 없이 그저 경로의 일부분이 될 뿐이다

 

 

사용자가 url로부터 보게 될 요소는 page.tsx!!

 

 

 

Not Found Routes

app 폴더에 not-found파일을 만들면 일치하지 않는 전역 url을 처리해 준다

 

 

usePathname

현재 url의 pathname을 알려주는 클라이언트 컴포넌트 훅

import { usePathname } from "next/navigation";

export default function Navigation() {
  const path = usePathname();
  console.log(path);

 

 

React client hook in Server Component 오류

 

서버 컴포넌트에서 리액트 클라이언트 훅을 사용하고 있을 때 발생하는 오류

'use client'를 코드에 추가해 클라이언트 컴포넌트로 바꿔줘야 한다

 

"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";

export default function Navigation() {
  const path = usePathname();
  console.log(path);

 

 

렌더링이란?

next.js가 리액트 컴포넌트를 브라우저가 이해할 수 있는 HTML로 변환하는 작업

 

 

CSR

평범한 리액트가 render 되는 방식은 client side rendering

브라우저가 rendering 작업을 한다는 것

 

리액트는 사용자 브라우저인 클라이언트 단에서 모든 rendering 작업을 수행해야 한다

클라이언트가 사용자 브라우저에 UI를 구축해야 하는 것!

 

이 방식이 가진 단점

 

1. 페이지 소스코드를 보면 실제 소스코드는 비어있다

브라우저가 모든 자바스크립트 파일을 다운로드하고 실행한 후에야 화면이 보인다

새로고침했을 때 소스코드가 잠깐 안 보이는 순간이 있는데 그 순간이 바로 자바스크립트 파일을 다운로드하는 과정

 

2. SEO 검색 엔진 최적화

검색 엔진이 보는 웹사이트는 비어있게 될 것이다

 

client side rendering은 모든 rendering, 즉 모든 UI 구축 작업이 클라이언트 측에서 일어나는 것

client는 JavaScript를 로드하고 그 후 JavaScript가 UI를 빌드한다

 

 

SSR

Next.js로 웹사이트를 빌드할 때는 자동적으로 server side rendeing이 된다

 

페이지 소스코드를 보면 페이지 내용들이 실제로 브라우저 코드에 있는 것을 확인할 수 있다

브라우저가 JavaScript가 로드될 때까지 기다릴 필요가 없다는 것을 의미한다

JavaScript가 활성화되지 않아도 사용자가 HTML을 볼 수 있게 되는 것!

 

Next.js 애플리케이션의 모든 페이지 안의 모든 컴포넌트들은 Next.js가 그것들을 우선 서버에서 render 한다!!!

server components든 client components든 'use cilent'를 갖고 있는 모든 컴포넌트는 우선 server side rendering이 된다!!

 

☆ 모든 컴포넌트와 페이지들은 먼저 백엔드에서 render 된다 ('use client' 사용 여부와 상관없이)

 

 

Hydration

단순 HTML을 React application으로 초기화하는 작업

SSR을 통해 만들어진 interactive 하지 않는 HTML을 클라이언트 측 자바스크립트를 사용해 interative 한 리액트 컴포넌트로 변환하는 과정

HTML을 실제 interactive 한 React component로 바꾸는 것(ex) 이벤트 리스너 추가)

원하는 경우 클라이언트 컴포넌트를 서버 컴포넌트 내에 포함할 수 있다

하지만 서버 컴포넌트를 클라이언트 컴포넌트 내에 포함시킬 수는 없다!

 

 

'use client'

hydration 과정이 모든 component에 대해 발생하지는 않는다

use client는 이 컴포넌트는 client에서 hydrated 되어야 한다고 말해주는 것

☆ use client는 오직 client에서만 render 된다는 것을 의미하지 않는다

백엔드에서 render 되고 프론트엔드에서 hydrate 됨을 의미한다

use client component를 사용하지 않는 모든 것들은 server component가 된다

server component는 server에서 먼저 render되고 hydrate는 되지 않는다

→ 사용자가 받아야 할 JavaScript 코드의 양이 줄어든다는 의미

"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";

export default function Navigation() {
  const path = usePathname();
  console.log(path);
  return (
    <nav>
      <ul>
        <li>
          <Link href="/">Home</Link>
          {path === "/" ? "🔥" : ""}
        </li>
        <li>
          <Link href="/about-us">About Us</Link>{" "}
          {path === "/about-us" ? "🔥" : ""}
        </li>
      </ul>
    </nav>
  );
}
import Navigation from "../components/navigation";

export default function Tomato() {
  return (
    <div>
      <Navigation />
    </div>
  );
}

 

 

1. 사용자에게 응답이 주어지기 전에 backend에서 애플리케이션을 pre render 한다
2. 모든 component를 가져가서 non interactive 한 HTML로 바꿔서 사용자에게 준다
3. use client 명령어를 가진 component가 hydrate 된다(interactive 된다)

 

 

 

Layouts

 페이지로 이동할 때마다 레이아웃 컴포넌트가 먼저 렌더링 되고 해당 페이지가 layout 컴포넌트의 children prop이 된다

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <Navigation />
      <body>{children}</body>
    </html>
  );
}

이렇게 해주면 각 컴포넌트마다 Navigation를 따로 추가해주지 않아도 된다

특정 페이지만을 위한 다른 레이아웃을 만들 수 있다

레이아웃은 서로 상쇄되지 않고 중첩이 가능하다

 

 

Route groups

route groups는 우리의 routes들을 그룹화해서 logical groups로 만들 수 있다

route groups는 폴더 이름을 괄호로 묶어줘야 한다  ex) (home)

☆ 괄호 폴더는 URL에 전혀 영향을 미치지 않는다

이걸 사용해 일부 레이아웃을 선택하거나 선택 해제하여 복잡한 일을 할 수 있다

 

 

Metadata

꼭 보내야 하는 object이고 메타데이터라고 불린다

export const metadata = {
  title: "Next.js",
  description: "Generated by Next.js",
};

안에 뭐가 있던지 페이지의 head 부분에 표시된다

메타데이터도 중첩이 가능하지만 실제로는 중첩되지 않고 병합된다

페이지나 레이아웃만 메타데이터를 내보낼 수 있다!!

컴포넌트에서는 메타데이터를 내보낼 수 없고 서버 컴포넌트에서만 있을 수 있다

메타데이터에 대한 템플릿도 만들 수 있다

import { Metadata } from "next";

export const metadata: Metadata = {
  title: {
    template: "%s | Next Movies",
    default: "Loading...",
  },
  description: "The best movies on the best framework",
};
// about-us폴더의 layout.tsx
export const metadata = {
  title: "About us",
};
// home폴더의 page.tsx
export const metadata = {
  title: "Home",
};

"About us"와 "Home"을 %s 자리에 넣어준다

import { Metadata } from "next";

export const metadata: Metadata = {
  title: "Not found",
};

타입스크립트를 사용하거나 도움을 받고 싶다면 이렇게 Metadata를 넣어줄 수 있다

 

 

Dynamic Routes

동적 세그먼트는 폴더 이름을 대괄호로 묶어 생성할 수 있다

ex) [id]

 

 

export default function MovieDetail(props) {
  console.log(props);
  return <h1>Movie</h1>;
}

 

http://localhost:3000/movies/1?region=kr 로 검색하면

 

파라미터는 URL에서 변수

export default function MovieDetail({
  params: { id },
}: {
  params: { id: string };
}) {
  return <h1>Movie {id}</h1>;
}

 

728x90

'Frontend > Next.js' 카테고리의 다른 글

[Next.js] Deployment  (3) 2024.10.15
[Next.js] Data Fetching  (0) 2024.10.14
[Next.js] Introduction  (0) 2024.07.29