Next.js의 클라이언트 측 라우팅

게시 됨: 2022-03-10
빠른 요약 ↬ Next.js에는 각 페이지가 파일 이름에 따라 자동으로 경로가 되는 파일 기반 라우팅 시스템이 있습니다. 각 페이지는 가장 일반적인 경로 패턴을 정의하는 데 사용할 수 있는 페이지 디렉토리에서 내보낸 기본 React 구성 요소입니다. 이 기사는 Next.js의 라우팅에 대해 알아야 할 거의 모든 것을 안내하고 관련 주제 및 개념의 방향을 알려줍니다.

하이퍼링크는 처음부터 웹의 보석 중 하나였습니다. MDN에 따르면 하이퍼링크는 웹을 웹으로 만드는 것 입니다. 문서 간의 링크와 같은 목적으로 사용되지만 고유한 웹 주소나 URL로 식별할 수 있는 다른 웹 페이지를 참조하는 데 주로 사용됩니다.

라우팅은 웹에 대한 하이퍼링크만큼이나 각 웹 응용 프로그램의 중요한 측면입니다. 요청을 처리하는 코드로 요청을 라우팅하는 메커니즘입니다. 라우팅과 관련하여 Next.js 페이지는 고유한 URL 경로로 참조되고 식별됩니다. 웹이 하이퍼링크 로 상호 연결된 탐색 웹 페이지 로 구성된 경우 각 Next.js 앱은 라우터로 상호 연결된 라우팅 가능한 페이지(경로 처리기 또는 경로)로 구성됩니다.

Next.js에는 특히 렌더링 및 데이터 가져오기를 고려할 때 압축을 풀기 어려울 수 있는 라우팅 지원이 내장되어 있습니다. Next.js에서 클라이언트 측 라우팅을 이해하기 위한 전제 조건으로 Next.js에서 라우팅, 렌더링 및 데이터 가져오기와 같은 개념에 대한 개요가 필요합니다.

이 기사는 Next.js에 익숙하고 라우팅을 처리하는 방법을 배우고자 하는 React 개발자에게 도움이 될 것입니다. 이 기사를 최대한 활용하려면 React 및 Next.js에 대한 실무 지식이 필요합니다. 이 기사는 전적으로 Next.js의 클라이언트 측 라우팅 및 관련 개념에 관한 것입니다.

라우팅 및 렌더링

라우팅과 렌더링은 서로 보완적이며 이 기사의 과정에서 큰 역할을 할 것입니다. 나는 Gaurav가 설명하는 방식을 좋아합니다.

라우팅 은 사용자가 웹사이트의 다른 페이지로 이동하는 프로세스입니다.

렌더링 은 해당 페이지를 UI에 배치하는 프로세스입니다. 특정 페이지에 대한 경로를 요청할 때마다 해당 페이지도 렌더링되지만 모든 렌더링이 경로의 결과인 것은 아닙니다.

5분 동안 그것에 대해 생각해 보십시오.

Next.js의 렌더링에 대해 이해해야 하는 것은 각 페이지가 수화라고 하는 프로세스를 통해 완전히 상호 작용하는 데 필요한 최소한의 JavaScript 코드와 함께 미리 미리 렌더링된다는 것입니다. Next.js가 이를 수행하는 방법은 사전 렌더링 형식에 크게 의존합니다. 정적 생성 또는 서버 측 렌더링 , 둘 다 사용되는 데이터 가져오기 기술과 밀접하게 연결되고 페이지용 HTML이 생성 될 때 분리됩니다.

데이터 가져오기 요구 사항에 따라 getStaticProps , getStaticPaths 또는 getServerSideProps , SWR 같은 클라이언트 측 데이터 가져오기 도구, 반응 쿼리 또는 가져오기와 같은 기존 데이터 가져오기 접근 방식과 같은 내장 데이터 가져오기 기능을 사용하고 있을 수 있습니다. render, fetch-the-render, render-as-you-fetch(Suspense 사용).

사전 렌더링(렌더링 전 — UI )은 라우팅을 보완하며 데이터 가져오기와 밀접하게 결합되어 있습니다. 따라서 이러한 개념은 상호 보완적이거나 밀접하게 관련되어 있지만 이 기사에서는 필요한 경우 관련 개념에 대한 참조와 함께 페이지 간 탐색(라우팅)에만 초점을 맞출 것입니다.

그런 점을 제외하고 기본적인 요점부터 시작하겠습니다. Next.js에는 페이지 개념을 기반으로 구축된 파일 시스템 기반 라우터가 있습니다.

점프 후 더! 아래에서 계속 읽기 ↓

페이지

Next.js의 페이지는 자동으로 경로로 사용할 수 있는 React 구성 요소입니다. .js , .jsx , .ts 또는 .tsx 와 같은 지원되는 파일 확장자를 사용하여 페이지 디렉토리에서 기본 내보내기로 내보내집니다.

일반적인 Next.js 앱은 page , publicstyles 와 같은 최상위 디렉토리가 있는 폴더 구조를 갖습니다.

 next-app ├── node_modules ├── pages │ ├── index.js // path: base-url (/) │ ├── books.jsx // path: /books │ └── book.ts // path: /book ├── public ├── styles ├── .gitignore ├── package.json └── README.md

각 페이지는 React 구성 요소입니다.

 // pages/books.js — `base-url/book` export default function Book() { return

서적

}

참고 : 페이지는 "라우트 핸들러"라고도 할 수 있습니다.

사용자 정의 페이지

이들은 페이지 디렉토리에 있지만 라우팅에 참여하지 않는 특수 페이지입니다. _app.js_document.js 와 같이 밑줄 기호가 접두사로 붙습니다.

  • _app.js
    이것은 페이지 폴더에 있는 사용자 정의 구성 요소입니다. Next.js는 이 구성 요소를 사용하여 페이지를 초기화합니다.
  • _document.js
    _app.js 와 마찬가지로 _document.js 는 Next.js가 애플리케이션의 <html><body> 태그를 보강하는 데 사용하는 사용자 지정 구성 요소입니다. 이것은 Next.js 페이지가 주변 문서의 마크업 정의를 건너뛰기 때문에 필요합니다.
 next-app ├── node_modules ├── pages │ ├── _app.js // ️ Custom page (unavailable as a route) │ ├── _document.jsx // ️ Custom page (unavailable as a route) │ └── index.ts // path: base-url (/) ├── public ├── styles ├── .gitignore ├── package.json └── README.md

페이지 간 연결

Next.js는 페이지 간에 클라이언트 측 경로 전환을 수행하는 데 사용할 수 있는 next/link API의 Link 구성 요소를 노출합니다.

 // Import the <Link/> component import Link from "next/link"; // This could be a page component export default function TopNav() { return ( <nav> <Link href="/">Home</Link> <Link href="/">Publications</Link> <Link href="/">About</Link> </nav> ) } // This could be a non-page component export default function Publications() { return ( <section> <TopNav/> {/* ... */} </section> ) }

Link 구성 요소는 페이지 여부에 관계없이 모든 구성 요소 내부에서 사용할 수 있습니다. 위의 예와 같이 가장 기본적인 형태로 사용될 때 Link 컴포넌트는 href 속성을 가진 하이퍼링크로 변환됩니다. ( Link 에 대한 자세한 내용은 아래의 다음/링크 섹션을 참조하세요.)

라우팅

Next.js 파일 기반 라우팅 시스템은 가장 일반적인 경로 패턴을 정의하는 데 사용할 수 있습니다. 이러한 패턴을 수용하기 위해 각 경로는 해당 정의에 따라 구분됩니다.

인덱스 라우트

기본적으로 Next.js 앱에서 초기 / 기본 경로는 자동으로 애플리케이션의 시작점 역할을 하는 pages/index.js /index.js입니다. 기본 URL이 localhost:3000 인 경우 이 인덱스 경로는 브라우저에서 애플리케이션의 기본 URL 수준에서 액세스할 수 있습니다.

인덱스 경로는 자동으로 각 디렉토리에 대한 기본 경로 역할을 하며 중복된 이름을 제거할 수 있습니다. 아래 디렉토리 구조는 //home 의 두 경로 경로를 노출합니다.

 next-app └── pages ├── index.js // path: base-url (/) └── home.js // path: /home

중첩 경로 를 사용하면 제거가 더 명확해집니다.

중첩 경로

pages/book 과 같은 경로는 한 수준 깊이입니다. 더 깊이 들어가려면 중첩된 폴더 구조가 필요한 중첩된 경로를 생성해야 합니다. https://www.smashingmagazine.com 의 기본 URL을 사용하면 아래와 유사한 폴더 구조를 만들어 https://www.smashingmagazine.com/printed-books/printed-books 경로에 액세스할 수 있습니다.

 next-app └── pages ├── index.js // top index route └── printed-books // nested route └── printed-books.js // path: /printed-books/printed-books

또는 인덱스 경로를 사용하여 경로 중복을 제거하고 https://www.smashingmagazine.com/printed-books 에서 인쇄된 책의 경로에 액세스할 수 있습니다.

 next-app └── pages ├── index.js // top index route └── printed-books // nested route └── index.js // path: /printed-books

동적 경로 는 중복을 제거하는 데도 중요한 역할을 합니다.

동적 경로

이전 예에서 우리는 모든 인쇄된 책에 접근하기 위해 인덱스 라우트를 사용합니다. 개별 책에 액세스하려면 다음과 같이 책마다 다른 경로를 만들어야 합니다.

 // ️ Don't do this. next-app └── pages ├── index.js // top index route └── printed-books // nested route ├── index.js // path: /printed-books ├── typesript-in-50-lessons.js // path: /printed-books/typesript-in-50-lessons ├── checklist-cards.js // path: /printed-books/checklist-cards ├── ethical-design-handbook.js // path: /printed-books/ethical-design-handbook ├── inclusive-components.js // path: /printed-books/inclusive-components └── click.js // path: /printed-books/click

이것은 매우 중복되고 확장 불가능하며 다음과 같은 동적 경로로 해결할 수 있습니다.

 // Do this instead. next-app └── pages ├── index.js // top index route └── printed-books ├── index.js // path: /printed-books └── [book-id].js // path: /printed-books/:book-id

대괄호 구문( [book-id] )은 동적 세그먼트 이며 파일에만 국한되지 않습니다. 아래 예와 같은 폴더와 함께 사용할 수도 있으므로 /printed-books/:book-id/author 경로에서 작성자를 사용할 수 있습니다.

 next-app └── pages ├── index.js // top index route └── printed-books ├── index.js // path: /printed-books └── [book-id] └── author.js // path: /printed-books/:book-id/author

경로의 동적 세그먼트는 useRouter() 후크의 query 개체를 사용하여 경로와 관련된 모든 연결 구성 요소에서 액세스할 수 있는 쿼리 매개변수로 노출됩니다. — (이에 대한 자세한 내용은 다음/라우터 API 섹션 ).

 // printed-books/:book-id import { useRouter } from 'next/router'; export default function Book() { const { query } = useRouter(); return ( <div> <h1> book-id <em>{query['book-id']}</em> </h1> </div> ); }
 // /printed-books/:book-id/author import { useRouter } from 'next/router'; export default function Author() { const { query } = useRouter(); return ( <div> <h1> Fetch author with book-id <em>{query['book-id']}</em> </h1> </div> ); }

Catch All Routes를 사용하여 동적 경로 세그먼트 확장

이전 예제에서 [book-id].js 와 같은 동적 경로 세그먼트 대괄호 구문을 보았습니다. 이 구문의 장점은 Catch-All Routes 를 사용하여 훨씬 더 많은 작업을 수행한다는 것입니다. 이름에서 이것이 무엇을 하는지 유추할 수 있습니다. 모든 경로를 포착합니다.

동적 예제를 볼 때 ID로 여러 책에 액세스하는 단일 경로에 대한 파일 생성 중복을 제거하는 데 도움이 되는 방법을 배웠습니다. 하지만 우리가 할 수 있는 다른 일이 있습니다.

특히 디렉토리 구조가 있는 /printed-books/:book-id 경로가 있습니다.

 next-app └── pages ├── index.js └── printed-books ├── index.js └── [book-id].js

카테고리와 같은 더 많은 세그먼트를 갖도록 경로를 업데이트하면 /printed-books/design/:book-id , /printed-books/engineering/:book-id 또는 더 나은 /printed-books/:category/:book-id 와 같은 결과가 나타날 수 있습니다. /printed-books/:category/:book-id .

출시 연도를 추가해 보겠습니다. /printed-books/:category/:release-year/:book-id . 패턴이 보이시나요? 디렉토리 구조는 다음과 같습니다.

 next-app └── pages ├── index.js └── printed-books └── [category] └── [release-year] └── [book-id].js

우리는 동적 경로에 대해 명명된 파일의 사용을 대체했지만 여하튼 여전히 다른 형태의 중복으로 끝났습니다. 음, 수정 사항이 있습니다. 깊게 중첩된 경로가 필요하지 않은 Catch All Routes:

 next-app └── pages ├── index.js └── printed-books └── [...slug].js

접두사가 세 개라는 점을 제외하고는 동일한 대괄호 구문을 사용합니다. JavaScript 확산 구문과 같은 점을 생각하십시오. 종합 경로를 사용하는 경우 카테고리( [category] ) 및 출시 연도( [release-year] )에 액세스하는 방법이 궁금할 수 있습니다. 두 가지 방법:

  1. 인쇄된 책 예의 경우 최종 목표는 책이고 각 책 정보에는 메타데이터가 첨부되어 있습니다.
  2. "슬러그" 세그먼트는 쿼리 매개변수의 배열로 반환됩니다.
 import { useRouter } from 'next/router'; export default function Book() { const { query } = useRouter(); // There's a brief moment where `slug` is undefined // so we use the Optional Chaining (?.) and Nullish coalescing operator (??) // to check if slug is undefined, then fall back to an empty array const [category, releaseYear, bookId] = query?.slug ?? []; return ( <table> <tbody> <tr> <th>Book Id</th> <td>{bookId}</td> </tr> <tr> <th>Category</th> <td>{category}</td> </tr> <tr> <th>Release Year</th> <td>{releaseYear}</td> </tr> </tbody> </table> ); }

다음은 /printed-books/[…slug] 경로에 대한 추가 예입니다.

쿼리 매개변수
/printed-books/click.js { "슬러그": ["클릭"] }
/printed-books/2020/click.js { “슬러그”: [“2020”, “클릭”] }
/printed-books/design/2020/click.js { “슬러그”: [“디자인”, “2020”, “클릭”] }

포괄 경로와 마찬가지로 /printed-books 경로는 대체 색인 경로를 제공하지 않는 한 404 오류를 발생시킵니다.

 next-app └── pages ├── index.js └── printed-books ├── index.js // path: /printed-books └── [...slug].js

포괄 경로가 "엄격"하기 때문입니다. 슬러그와 일치하거나 오류가 발생합니다. 포괄 경로와 함께 인덱스 경로를 생성하지 않으려면 선택적 포괄 경로 를 대신 사용할 수 있습니다.

선택적 포괄 경로로 동적 경로 세그먼트 확장

구문은 catch-all-routes와 동일하지만 대신 이중 대괄호가 사용됩니다.

 next-app └── pages ├── index.js └── printed-books └── [[...slug]].js

이 경우 포괄 경로(슬러그)는 선택 사항이며 사용할 수 없는 경우 쿼리 매개변수 없이 [[…slug]].js 경로 처리기로 렌더링된 /printed-books 경로로 대체됩니다.

인덱스 경로와 함께 catch-all을 사용하거나 단독으로 선택적인 catch-all 경로를 사용합니다. 포괄 및 선택적 포괄 경로를 함께 사용하지 마십시오.

경로 우선 순위

가장 일반적인 라우팅 패턴을 정의할 수 있는 기능은 "블랙 스완"이 될 수 있습니다. 경로 충돌의 가능성은 가장 특히 동적 경로가 작업되기 시작할 때 다가오는 위협입니다.

그렇게 하는 것이 합리적일 때 Next.js는 경로 충돌에 대해 오류 형태로 알려줍니다. 그렇지 않은 경우 특정성에 따라 경로에 우선 순위를 적용합니다.

예를 들어, 같은 수준에 둘 이상의 동적 경로가 있는 것은 오류입니다.

 // This is an error // Failed to reload dynamic routes: Error: You cannot use different slug names for the // same dynamic path ('book-id' !== 'id'). next-app └── pages ├── index.js └── printed-books ├── [book-id].js └── [id].js

아래에 정의된 경로를 자세히 살펴보면 충돌 가능성이 있음을 알 수 있습니다.

 // Directory structure flattened for simplicity next-app └── pages ├── index.js // index route (also a predefined route) └── printed-books ├── index.js ├── tags.js // predefined route ├── [book-id].js // handles dynamic route └── [...slug].js // handles catch all route

예를 들어 다음과 같이 답해 보십시오. /printed-books/inclusive-components 경로를 처리하는 경로는 무엇입니까?

  • /printed-books/[book-id].js 또는
  • /printed-books/[…slug].js .

답은 경로 처리기의 "특이성"에 있습니다. 사전 정의된 경로가 먼저 나오고 동적 경로가 그 다음에 오고 포괄 경로가 뒤따릅니다. 다음 단계를 통해 경로 요청/처리 모델을 의사 코드로 생각할 수 있습니다.

  1. 경로를 처리할 수 있는 미리 정의된 경로 처리기 가 있습니까?
    • true — 경로 요청을 처리합니다.
    • false - 2로 이동합니다.
  2. 경로를 처리할 수 있는 동적 경로 처리기 가 있습니까?
    • true — 경로 요청을 처리합니다.
    • false - 3으로 이동합니다.
  3. 경로를 처리할 수 있는 포괄적인 경로 처리기 가 있습니까?
    • true — 경로 요청을 처리합니다.
    • false — 404 페이지를 찾을 수 없습니다.

따라서 /printed-books/[book-id].js 가 이깁니다.

다음은 더 많은 예입니다.

노선 경로 처리기 경로 유형
/printed-books /printed-books 인덱스 경로
/printed-books/tags /printed-books/tags.js 미리 정의된 경로
/printed-books/inclusive-components /printed-books/[book-id].js 동적 경로
/printed-books/design/inclusive-components /printed-books/[...slug].js 포괄 경로

next/link API

next/link API는 클라이언트 측 경로 전환을 수행하기 위한 선언적 방법으로 Link 구성 요소를 노출합니다.

 import Link from 'next/link' function TopNav() { return ( <nav> <Link href="/">Smashing Magazine</Link> <Link href="/articles">Articles</Link> <Link href="/guides">Guides</Link> <Link href="/printed-books">Books</Link> </nav> ) }

Link 구성 요소는 일반 HTML 하이퍼링크로 확인됩니다. 즉, <Link href="/">Smashing Magazine</Link><a href="/">Smashing Magazine</a> 으로 변환됩니다.

href prop은 Link 컴포넌트에 필요한 유일한 prop입니다. Link 구성 요소에서 사용할 수 있는 전체 props 목록은 문서를 참조하세요.

알아야 할 Link 구성 요소의 다른 메커니즘이 있습니다.

동적 세그먼트가 있는 경로

Next.js 9.5.3 이전에는 동적 경로에 Link 한다는 것은 다음과 같이 Linkhrefas prop을 모두 제공해야 함을 의미했습니다.

 import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href="/printed-books/[printed-book-id]" as={`/printed-books/${printedBook.id}`} > {printedBook.name} </Link> )); }

이를 통해 Next.js가 동적 매개변수에 대한 href를 보간할 수 있었지만 지루하고 오류가 발생하기 쉬우며 다소 필수적이었으며 이제 Next.js 10 릴리스와 함께 대부분의 사용 사례에 대해 수정되었습니다.

이 수정 사항은 이전 버전과도 호환됩니다. ashref 를 모두 사용했다면 아무 것도 중단되지 않습니다. 새 구문을 적용하려면 href prop 및 해당 값을 버리고 as prop의 이름을 아래 예와 같이 href 로 바꿉니다.

 import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={`/printed-books/${printedBook.id}`}>{printedBook.name}</Link> )); }

href 자동 해결을 참조하세요.

passHref 소품의 사용 사례

아래 스니펫을 자세히 살펴보세요.

 import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; // Say this has some sort of base styling attached function CustomLink({ href, name }) { return <a href={href}>{name}</a>; } export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={`/printed-books/${printedBook.id}`} passHref> <CustomLink name={printedBook.name} /> </Link> )); }

passHrefLink 구성 요소가 href 속성을 CustomLink 하위 구성 요소로 전달하도록 합니다. Link 구성 요소가 하이퍼링크 <a> 태그를 반환하는 구성 요소를 감싸는 경우 필수입니다. 사용 사례는 styled-components와 같은 라이브러리를 사용하거나 단일 자식만 예상하므로 Link 구성 요소에 여러 자식을 전달해야 하기 때문일 수 있습니다.

자세한 내용은 문서를 참조하세요.

URL 개체

Link 구성 요소의 href prop은 자동으로 URL 문자열로 형식이 지정되는 query 와 같은 속성이 있는 URL 개체일 수도 있습니다.

printedBooks 개체를 사용하여 아래 예제는 다음으로 연결됩니다.

  1. /printed-books/ethical-design?name=Ethical+Design
  2. /printed-books/design-systems?name=Design+Systems .
 import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={{ pathname: `/printed-books/${printedBook.id}`, query: { name: `${printedBook.name}` }, }} > {printedBook.name} </Link> )); }

pathname 에 동적 세그먼트를 포함하는 경우 쿼리가 pathname 에서 보간되도록 쿼리 개체에 속성으로 포함해야 합니다.

 import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; // In this case the dynamic segment `[book-id]` in pathname // maps directly to the query param `book-id` export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={{ pathname: `/printed-books/[book-id]`, query: { 'book-id': `${printedBook.id}` }, }} > {printedBook.name} </Link> )); }

위의 예에는 경로가 있습니다.

  1. /printed-books/ethical-design
  2. /printed-books/design-systems .

VSCode에서 href 속성을 검사하면 href 속성이 Url 유형인 LinkProps 유형을 찾을 수 있습니다. 이 유형은 앞에서 언급한 것처럼 string 또는 UrlObject 입니다.

VSCode에서 검사된 LinkProps 유형의 스크린샷
LinkProps 에서 LinkProps 검사. (큰 미리보기)

UrlObject 를 검사하면 속성이 있는 인터페이스로 이어집니다.

VSCode에서 검사된 <code>UrlObject</code>의 스크린샷
VSCode에서 UrlObject 검사. (큰 미리보기)

Node.js URL 모듈 문서에서 이러한 속성에 대해 자세히 알아볼 수 있습니다.

해시의 한 가지 사용 사례는 페이지의 특정 섹션에 링크하는 것입니다.

 import Link from 'next/link'; const printedBooks = [{ name: 'Ethical Design', id: 'ethical-design' }]; export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={{ pathname: `/printed-books/${printedBook.id}`, hash: 'faq', }} > {printedBook.name} </Link> )); }

하이퍼링크는 /printed-books/ethical-design#faq 됩니다.

문서에서 자세히 알아보세요.

next/router API

next/link 가 선언적이면 next/router 가 필수입니다. 모든 기능 구성 요소 내부의 router 개체에 액세스할 수 있는 useRouter 후크를 노출합니다. 이 후크를 사용하여 라우팅을 수동으로 수행할 수 있습니다. 특히 next/link 가 충분하지 않거나 라우팅에 "후크"해야 하는 특정 시나리오에서 특히 그렇습니다.

 import { useRouter } from 'next/router'; export default function Home() { const router = useRouter(); function handleClick(e) { e.preventDefault(); router.push(href); } return ( <button type="button" onClick={handleClick}>Click me</button> ) }

useRouter 는 React 후크이며 클래스와 함께 사용할 수 없습니다. 클래스 구성 요소에 router 개체가 필요합니까? withRouter 사용하십시오.

 import { withRouter } from 'next/router'; function Home({router}) { function handleClick(e) { e.preventDefault(); router.push(href); } return ( <button type="button" onClick={handleClick}>Click me</button> ) } export default withRouter(Home);

router 개체

useRouter 후크와 withRouter 고차 구성 요소 모두 현재 페이지의 URL 상태에 대한 정보를 제공하는 pathname , query , asPathbasePath , locale , localesdefaultLocale 에 대한 정보를 제공하는 defaultLocale과 같은 속성을 가진 라우터 객체를 반환합니다. 활성, 지원 또는 현재 기본 로케일.

라우터 객체에는 새 URL 항목을 기록 스택에 추가하여 새 URL로 이동하기 위한 push 와 같은 메서드도 있습니다. replace 는 push와 유사하지만 기록 스택에 새 URL 항목을 추가하는 대신 현재 URL을 대체합니다.

라우터 개체에 대해 자세히 알아보세요.

next.config.js 를 사용한 사용자 지정 경로 구성

이것은 특정 Next.js 동작을 구성하는 데 사용할 수 있는 일반 Node.js 모듈입니다.

 module.exports = { // configuration options }

next.config.js 를 업데이트할 때마다 서버를 다시 시작해야 합니다. 더 알아보기.

기본 경로

Next.js의 초기/기본 경로는 / 경로가 있는 pages/index.js /index.js라고 언급했습니다. 이것은 구성 가능하며 기본 경로를 도메인의 하위 경로로 만들 수 있습니다.

 module.exports = { // old default path: / // new default path: /dashboard basePath: '/dashboard', };

이러한 변경 사항은 모든 / 경로가 /dashboard 로 라우팅된 애플리케이션에 자동으로 적용됩니다.

이 기능은 Next.js 9.5 이상에서만 사용할 수 있습니다. 더 알아보기.

후행 슬래시

기본적으로 각 URL 끝에 후행 슬래시를 사용할 수 없습니다. 그러나 다음을 사용하여 전환할 수 있습니다.

 module.exports = { trailingSlash: true };
 # trailingSlash: false /printed-books/ethical-design#faq # trailingSlash: true /printed-books/ethical-design/#faq

기본 경로와 후행 슬래시 기능은 모두 Next.js 9.5 이상에서만 사용할 수 있습니다.

결론

라우팅은 Next.js 애플리케이션의 가장 중요한 부분 중 하나이며 페이지 개념을 기반으로 구축된 파일 시스템 기반 라우터에 반영됩니다. 페이지는 가장 일반적인 경로 패턴을 정의하는 데 사용할 수 있습니다. 라우팅과 렌더링의 개념은 밀접하게 관련되어 있습니다. 자신만의 Next.js 앱을 빌드하거나 Next.js 코드베이스에서 작업할 때 이 기사의 교훈을 활용하십시오. 자세한 내용은 아래 리소스를 확인하세요.

관련 리소스

  • Pages용 Next.js 공식 문서
  • 데이터 가져오기에 대한 Next.js 공식 문서
  • next.config.js에 대한 Next.js 공식 문서
  • Next.js 10: href 자동 해결
  • next/link에 대한 Next.js 공식 문서
  • next/router에 대한 Next.js 공식 문서