Định tuyến phía máy khách trong Next.js

theanh

Administrator
Nhân viên
Siêu liên kết đã là một trong những viên ngọc của Web kể từ khi ra đời . Theo MDN, siêu liên kết là thứ tạo nên Web, một trang web. Mặc dù được sử dụng cho các mục đích như liên kết giữa các tài liệu, mục đích chính của nó là tham chiếu đến các trang web khác nhau có thể nhận dạng bằng một địa chỉ web duy nhất hoặc URL.

Định tuyến là một khía cạnh quan trọng của mỗi ứng dụng web cũng giống như siêu liên kết đến Web. Đây là một cơ chế mà qua đó các yêu cầu được định tuyến đến mã xử lý chúng. Liên quan đến định tuyến, các trang Next.js được tham chiếu và có thể nhận dạng bằng một đường dẫn URL duy nhất. Nếu Web bao gồm các trang web điều hướng được kết nối với nhau bằng siêu liên kết, thì mỗi ứng dụng Next.js bao gồm các trang có thể định tuyến (trình xử lý tuyến đường hoặc tuyến đường) được kết nối với nhau bằng bộ định tuyến.

Next.js có hỗ trợ tích hợp cho định tuyến có thể khó sử dụng để giải nén, đặc biệt là khi xem xét kết xuất và truy xuất dữ liệu. Là điều kiện tiên quyết để hiểu định tuyến phía máy khách trong Next.js, cần phải có tổng quan về các khái niệm như định tuyến, kết xuất và truy xuất dữ liệu trong Next.js.

Bài viết này sẽ có ích cho các nhà phát triển React đã quen thuộc với Next.js và muốn tìm hiểu cách xử lý định tuyến. Bạn cần có kiến thức thực tế về React và Next.js để tận dụng tối đa bài viết, bài viết chỉ nói về định tuyến phía máy khách và các khái niệm liên quan trong Next.js.

Định tuyến và kết xuất​

Định tuyến và kết xuất bổ sung cho nhau và sẽ đóng vai trò rất lớn trong suốt bài viết này. Tôi thích cách Gaurav giải thích chúng:
Định tuyến là quá trình mà người dùng được điều hướng đến các trang khác nhau trên một trang web.

Kết xuất là quá trình đưa các trang đó vào UI. Mỗi khi bạn yêu cầu một tuyến đường đến một trang cụ thể, bạn cũng đang hiển thị trang đó, nhưng không phải mọi lần hiển thị đều là kết quả của một tuyến đường.
Hãy dành năm phút để suy nghĩ về điều đó.

Điều bạn cần hiểu về việc hiển thị trong Next.js là mỗi trang đều được hiển thị trước cùng với mã JavaScript tối thiểu cần thiết để trang đó có thể tương tác hoàn toàn thông qua một quy trình được gọi là hydrat hóa. Cách Next.js thực hiện điều này phụ thuộc rất nhiều vào hình thức dựng trước: Tạo tĩnh hoặc Kết xuất phía máy chủ, cả hai đều được kết nối chặt chẽ với kỹ thuật truy xuất dữ liệu được sử dụng và được phân tách theo thời điểm HTML cho một trang được tạo.

Tùy thuộc vào yêu cầu truy xuất dữ liệu của bạn, bạn có thể thấy mình đang sử dụng các hàm truy xuất dữ liệu tích hợp như getStaticProps, getStaticPaths hoặc getServerSideProps, các công cụ truy xuất dữ liệu phía máy khách như SWR, react-query hoặc các phương pháp truy xuất dữ liệu truyền thống như fetch-on-render, fetch-then-render, render-as-you-fetch (với Suspense).

Kết xuất trước (trước khi kết xuất — đến UI) bổ sung cho Định tuyến và kết hợp chặt chẽ với việc truy xuất dữ liệu — toàn bộ chủ đề của riêng nó trong Next.js. Vì vậy, trong khi các khái niệm này bổ sung cho nhau hoặc có liên quan chặt chẽ, bài viết này sẽ chỉ tập trung vào điều hướng đơn thuần giữa các trang (định tuyến), với các tham chiếu đến các khái niệm liên quan khi cần thiết.

Sau khi giải quyết vấn đề đó, chúng ta hãy bắt đầu với cốt lõi cơ bản: Next.js có bộ định tuyến dựa trên hệ thống tệp được xây dựng trên khái niệm về trang.

Trang​

Trang trong Next.js là các Thành phần React có sẵn tự động dưới dạng các tuyến. Chúng được xuất dưới dạng xuất mặc định từ thư mục trang với các phần mở rộng tệp được hỗ trợ như .js, .jsx, .ts hoặc .tsx.

Một ứng dụng Next.js thông thường sẽ có cấu trúc thư mục với các thư mục cấp cao nhất như pages, publicstyles.
Mã:
next-app├── node_modules├── pages│ ├── index.js // đường dẫn: base-url (/)│ ├── books.jsx // đường dẫn: /books│ └── book.ts // đường dẫn: /book├── public├── styles├── .gitignore├── package.json└── README.md
Mỗi trang là một thành phần React:
Mã:
// pages/books.js — `base-url/book`export default function Book() { return [HEADING=1]Sách[/HEADING]}
Lưu ý: Lưu ý rằng các trang cũng có thể được gọi là "trình xử lý tuyến đường".

Các trang tùy chỉnh​

Đây là các trang đặc biệt nằm trong thư mục pages nhưng không tham gia vào định tuyến. Chúng được thêm tiền tố là ký hiệu gạch dưới, như trong _app.js_document.js.
  • _app.js
    Đây là một thành phần tùy chỉnh nằm trong thư mục pages. Next.js sử dụng thành phần này để khởi tạo các trang.
  • _document.js
    Giống như _app.js, _document.js là một thành phần tùy chỉnh mà Next.js sử dụng để tăng cường các thẻ của ứng dụng của bạn. Điều này là cần thiết vì các trang Next.js bỏ qua định nghĩa của đánh dấu tài liệu xung quanh.
Mã:
next-app├── node_modules├── pages│ ├── _app.js // ⚠️ Trang tùy chỉnh (không khả dụng dưới dạng tuyến đường)│ ├── _document.jsx // ⚠️ Trang tùy chỉnh (không khả dụng dưới dạng tuyến đường)│ └── index.ts // đường dẫn: base-url (/)├── public├── styles├── .gitignore├── package.json└── README.md

Liên kết giữa các trang​

Next.js hiển thị thành phần Link từ API next/link có thể được sử dụng để thực hiện chuyển đổi tuyến đường phía máy khách giữa các trang.
Mã:
// Nhập thành phần 
[*] import Link from "next/link";// Đây có thể là một thành phần trangexport default function TopNav() { return (  Home Publications About  )}// Đây có thể là một thành phần không phải trangexport default function Publications() { return (   {/* ... */}  )}
Thành phần Link có thể được sử dụng bên trong bất kỳ thành phần nào, trang hoặc không. Khi được sử dụng ở dạng cơ bản nhất như trong ví dụ trên, thành phần Link sẽ chuyển thành siêu liên kết có thuộc tính href. (Thông tin thêm về Liên kết trong phần tiếp theo/liên kết bên dưới.)

Định tuyến​

Hệ thống định tuyến dựa trên tệp Next.js có thể được sử dụng để xác định các mẫu định tuyến phổ biến nhất. Để phù hợp với các mẫu này, mỗi tuyến được phân tách dựa trên định nghĩa của nó.

Các tuyến chỉ mục​

Theo mặc định, trong ứng dụng Next.js của bạn, tuyến ban đầu/mặc định là pages/index.js tự động đóng vai trò là điểm bắt đầu của ứng dụng của bạn dưới dạng /. Với URL cơ sở là localhost:3000, tuyến chỉ mục này có thể được truy cập ở cấp URL cơ sở của ứng dụng trong trình duyệt.

Các tuyến chỉ mục tự động hoạt động như tuyến mặc định cho mỗi thư mục và có thể loại bỏ sự trùng lặp trong đặt tên. Cấu trúc thư mục bên dưới hiển thị hai đường dẫn tuyến đường: //home.
Mã:
next-app└── pages ├── index.js // path: base-url (/) └── home.js // path: /home
Việc loại bỏ rõ ràng hơn với các tuyến đường lồng nhau.

Các tuyến đường lồng nhau​

Một tuyến đường như pages/book có độ sâu một cấp. Để đi sâu hơn là tạo các tuyến đường lồng nhau, đòi hỏi phải có cấu trúc thư mục lồng nhau. Với url cơ sở là https://www.smashingmagazine.com, bạn có thể truy cập tuyến đường https://www.smashingmagazine.com/printed-books/printed-books bằng cách tạo cấu trúc thư mục tương tự như bên dưới:
Mã:
next-app└── pages ├── index.js // tuyến đường chỉ mục hàng đầu └── printed-books // tuyến đường lồng nhau └── printed-books.js // đường dẫn: /printed-books/printed-books
Hoặc loại bỏ sự trùng lặp đường dẫn với các tuyến đường chỉ mục và truy cập tuyến đường dành cho sách in tại https://www.smashingmagazine.com/printed-books.
Mã:
next-app└── pages ├── index.js // tuyến chỉ mục hàng đầu └── printed-books // tuyến lồng nhau └── index.js // đường dẫn: /printed-books
Các tuyến động cũng đóng vai trò quan trọng trong việc loại bỏ sự trùng lặp.

Các tuyến động​

Từ ví dụ trước, chúng ta sử dụng tuyến chỉ mục để truy cập tất cả các sách đã in. Để truy cập từng cuốn sách, cần tạo các tuyến khác nhau cho từng cuốn sách như sau:
Mã:
// ⚠️ Đừng làm như vậy.next-app└── trang ├── index.js // tuyến chỉ mục hàng đầu └── printed-books // tuyến lồng nhau ├── index.js // đường dẫn: /printed-books ├── typesript-in-50-lessons.js // đường dẫn: /printed-books/typesript-in-50-lessons ├── checklist-cards.js // đường dẫn: /printed-books/checklist-cards ├── ethical-design-handbook.js // đường dẫn: /printed-books/ethical-design-handbook ├── inclusive-components.js // đường dẫn: /printed-books/inclusive-components └── click.js // đường dẫn: /printed-books/click
rất thừa, không thể mở rộng quy mô và có thể khắc phục bằng các tuyến động như:
Mã:
// ✅ Hãy thực hiện thao tác này thay thế.next-app└── pages ├── index.js // tuyến chỉ mục hàng đầu └── printed-books ├── index.js // đường dẫn: /printed-books └── [book-id].js // đường dẫn: /printed-books/:book-id
Cú pháp ngoặc — [book-id] — là phân đoạn động và không chỉ giới hạn ở các tệp. Nó cũng có thể được sử dụng với các thư mục như ví dụ bên dưới, làm cho tác giả có sẵn tại tuyến đường /printed-books/:book-id/author.
Mã:
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
Các phân đoạn động của một tuyến đường được hiển thị dưới dạng tham số truy vấn có thể được truy cập trong bất kỳ thành phần kết nối nào có liên quan đến tuyến đường với đối tượng query của hook useRouter() — (Thông tin thêm về điều này trong API next/router section).
Mã:
// printed-books/:book-idimport { useRouter } from 'next/router';export default function Book() { const { query } = useRouter(); return (  [HEADING=1] book-id [I]{query['book-id']}[/I] [/HEADING]  );}
Mã:
// /printed-books/:book-id/authorimport { useRouter } from 'next/router';export default function Author() { const { query } = useRouter(); return (  [HEADING=1] Lấy tác giả với book-id [I]{query['book-id']}[/I] [/HEADING]  );}

Mở rộng các phân đoạn tuyến động với Catch All Routes​

Bạn đã thấy cú pháp ngoặc phân đoạn tuyến động như trong ví dụ trước với [book-id].js. Điểm tuyệt vời của cú pháp này là nó đưa mọi thứ đi xa hơn nữa với Catch-All Routes. Bạn có thể suy ra tác dụng của cú pháp này từ tên: nó bắt tất cả các tuyến.

Khi chúng ta xem xét ví dụ động, chúng ta đã biết cách nó giúp loại bỏ sự dư thừa khi tạo tệp cho một tuyến duy nhất để truy cập nhiều sách bằng ID của chúng. Nhưng có một điều khác mà chúng ta có thể làm.

Cụ thể, chúng ta có đường dẫn /printed-books/:book-id, với cấu trúc thư mục:
Mã:
next-app└── pages ├── index.js └── printed-books ├── index.js └── [book-id].js
Nếu chúng ta cập nhật đường dẫn để có nhiều phân đoạn hơn như danh mục, chúng ta có thể kết thúc với thứ gì đó như sau: /printed-books/design/:book-id, /printed-books/engineering/:book-id hoặc tốt hơn nữa là /printed-books/:category/:book-id.

Hãy thêm năm phát hành: /printed-books/:category/:release-year/:book-id. Bạn có thấy một mẫu không? Cấu trúc thư mục trở thành:
Mã:
next-app└── pages ├── index.js └── printed-books └── [category] └── [release-year] └── [book-id].js
Chúng tôi đã thay thế việc sử dụng các tệp được đặt tên cho các tuyến động, nhưng bằng cách nào đó vẫn kết thúc với một hình thức dự phòng khác. Vâng, có một cách khắc phục: Catch All Routes giúp loại bỏ nhu cầu về các tuyến được lồng sâu:
Mã:
next-app└── pages ├── index.js └── printed-books └── [...slug].js
Nó sử dụng cùng cú pháp ngoặc vuông ngoại trừ việc nó được thêm tiền tố là ba dấu chấm. Hãy nghĩ về các dấu chấm như cú pháp lan truyền JavaScript. Bạn có thể tự hỏi: Nếu tôi sử dụng các tuyến catch-all, thì làm thế nào để tôi truy cập vào danh mục ([category]) và năm phát hành ([release-year]). Có hai cách:
  1. Trong trường hợp ví dụ về printed-books, mục tiêu cuối cùng là cuốn sách và mỗi thông tin về cuốn sách sẽ có siêu dữ liệu được đính kèm hoặc
  2. Các phân đoạn "slug" được trả về dưới dạng một mảng các tham số truy vấn.
Mã:
import { useRouter } from 'next/router';export default function Book() { const { query } = useRouter(); // Có một khoảnh khắc ngắn mà `slug` không được xác định // vì vậy chúng ta sử dụng Optional Chaining (?.) và toán tử hợp nhất Nullish (??) // để kiểm tra xem slug có được xác định không, sau đó quay lại một mảng trống const [category, releaseYear, bookId] = query?.slug ?? []; trả về ( [TABLE]  [TR] [TH]Mã số sách[/TH] [TD]{bookId}[/TD] [/TR] [TR] [TH]Thể loại[/TH] [TD]{category}[/TD] [/TR] [TR] [TH]Năm phát hành[/TH] [TD]{releaseYear}[/TD] [/TR]  [/TABLE] );}
Sau đây là ví dụ thêm cho tuyến đường /printed-books/[…slug]:
Đường dẫnTham số truy vấn
/printed-books/click.js{ “slug”: [“click”] }
/printed-books/2020/click.js{ “slug”: [“2020”, “click”] }
/printed-books/design/2020/click.js{ “slug”: [“design”, “2020”, “click”] }
Cũng giống như catch-all route, route /printed-books sẽ trả về lỗi 404 trừ khi bạn cung cấp route index dự phòng.
Mã:
next-app└── pages ├── index.js └── printed-books ├── index.js // path: /printed-books └── [...slug].js
Điều này là do route catch-all là "strict". Nó khớp với slug hoặc trả về lỗi. Nếu bạn muốn tránh tạo các tuyến chỉ mục cùng với các tuyến bắt tất cả, bạn có thể sử dụng tuyến bắt tất cả tùy chọn thay thế.

Mở rộng các phân đoạn tuyến động bằng các tuyến bắt tất cả tùy chọn​

Cú pháp giống như catch-all-routes, nhưng thay vào đó là dấu ngoặc vuông đôi.
Mã:
next-app└── pages ├── index.js └── printed-books └── [[...slug]].js
Trong trường hợp này, tuyến bắt tất cả (slug) là tùy chọn và nếu không khả dụng, tuyến sẽ chuyển sang đường dẫn /printed-books, được hiển thị bằng tuyến [[…slug]].js handler, không có bất kỳ tham số truy vấn nào.
"Sử dụng catch-all cùng với các tuyến chỉ mục hoặc chỉ sử dụng các tuyến catch-all tùy chọn. Tránh sử dụng các tuyến catch-all và các tuyến catch-all tùy chọn cùng nhau."

Thứ tự ưu tiên của các tuyến​

Khả năng có thể xác định các mẫu định tuyến phổ biến nhất có thể là một "thiên nga đen". Khả năng xảy ra xung đột giữa các tuyến là một mối đe dọa đang rình rập, đặc biệt là khi bạn bắt đầu xử lý các tuyến động.

Khi cần thiết, Next.js sẽ cho bạn biết về các xung đột tuyến dưới dạng lỗi. Khi không, nó sẽ áp dụng thứ tự ưu tiên cho các tuyến theo tính đặc thù của chúng.

Ví dụ, sẽ là lỗi nếu có nhiều hơn một tuyến động ở cùng một cấp độ.
Mã:
// ❌ Đây là lỗi// Không tải lại được các tuyến động: Lỗi: Bạn không thể sử dụng các tên slug khác nhau cho // cùng một đường dẫn động ('book-id' !== 'id').next-app└── pages ├── index.js └── printed-books ├── [book-id].js └── [id].js
Nếu bạn xem xét kỹ các tuyến đường được xác định bên dưới, bạn sẽ nhận thấy khả năng xảy ra xung đột.
Mã:
// Cấu trúc thư mục được làm phẳng để đơn giản hơnnext-app└── pages ├── index.js // tuyến đường chỉ mục (cũng là tuyến đường được xác định trước) └── printed-books ├── index.js ├── tags.js // tuyến đường được xác định trước ├── [book-id].js // xử lý tuyến đường động └── [...slug].js // xử lý catch all route
Ví dụ, hãy thử trả lời câu hỏi này: route nào xử lý đường dẫn /printed-books/inclusive-components?
  • /printed-books/[book-id].js, hay
  • /printed-books/[…slug].js.
Câu trả lời nằm ở "tính đặc thù" của trình xử lý route. Các route được xác định trước sẽ xuất hiện trước, theo sau là các route động, rồi đến các route catch-all. Bạn có thể coi mô hình yêu cầu/xử lý route như một mã giả với các bước sau:
  1. trình xử lý tuyến đường được xác định trước có thể xử lý tuyến đường không?
    • true — xử lý yêu cầu tuyến đường.
    • false — chuyển đến 2.
  2. trình xử lý tuyến đường động có thể xử lý tuyến đường không?
    • true — xử lý yêu cầu tuyến đường.
    • false — chuyển đến 3.
  3. trình xử lý tuyến đường catch-all có thể xử lý tuyến đường không?
    • true — xử lý yêu cầu tuyến đường.
    • false — đưa ra lỗi 404 không tìm thấy trang.
Do đó, /printed-books/[book-id].js thắng.

Sau đây là thêm một số ví dụ:
Tuyến đườngTrình xử lý tuyến đườngLoại tuyến đường
/printed-books/printed-booksTuyến đường chỉ mục
/printed-books/tags/printed-books/tags.jsTuyến đường được xác định trước
/printed-books/inclusive-components/printed-books/[book-id].jsĐộng route
/printed-books/design/inclusive-components/printed-books/[...slug].jsCatch-all route

API next/link

API next/link trình bày thành phần Link như một cách khai báo để thực hiện chuyển đổi tuyến đường phía máy khách.
Mã:
import Link from 'next/link'function TopNav() { return (  
[*] Smashing Magazine Articles Guides Books  )}
Thành phần Link sẽ giải quyết thành một siêu liên kết HTML thông thường. Nghĩa là, Smashing Magazine sẽ giải quyết thành [URL=/]Smashing Magazine[/URL].

Property href là prop duy nhất bắt buộc đối với thành phần Link. Xem docs để biết danh sách đầy đủ các prop có sẵn trên thành phần Link.

Có những cơ chế khác của thành phần Link mà bạn cần lưu ý.

Các tuyến đường có phân đoạn động​

Trước Next.js 9.5.3, Liên kết với các tuyến đường động có nghĩa là bạn phải cung cấp cả prop hrefas cho Link như trong:
Mã:
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) => (  {printedBook.name}  ));}
Mặc dù điều này cho phép Next.js nội suy href cho các tham số động, nhưng nó rất tẻ nhạt, dễ xảy ra lỗi và có phần bắt buộc, và hiện đã được sửa cho phần lớn các trường hợp sử dụng với bản phát hành Next.js 10.

Bản sửa lỗi này cũng tương thích ngược. Nếu bạn đã sử dụng cả ashref, không có gì bị hỏng. Để áp dụng cú pháp mới, hãy loại bỏ href prop và giá trị của nó, rồi đổi tên as prop thành href như trong ví dụ bên dưới:
Mã:
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) => ( {printedBook.name} ));}

Các trường hợp sử dụng cho passHref Prop​

Hãy xem kỹ đoạn trích dưới đây:
Mã:
import Link from 'next/link';const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' },];// Giả sử có một số kiểu dáng cơ sở được đính kèmfunction CustomLink({ href, name }) { return {name};}export default function PrintedBooks() { return printedBooks.map((printedBook) => (    ));}
Các prop passHref buộc thành phần Link truyền prop href xuống thành phần con CustomLink. Điều này là bắt buộc nếu thành phần Link bao quanh một thành phần trả về thẻ siêu liên kết . Trường hợp sử dụng của bạn có thể là do bạn đang sử dụng một thư viện như styled-components hoặc nếu bạn cần truyền nhiều phần tử con cho thành phần Link vì nó chỉ mong đợi một phần tử con duy nhất.
“Xem docs để tìm hiểu thêm.”

Đối tượng URL​

Thuộc tính href của thành phần Link cũng có thể là một đối tượng URL có các thuộc tính như query được định dạng tự động thành chuỗi URL.

Với đối tượng printedBooks, ví dụ bên dưới sẽ liên kết đến:
  1. /printed-books/ethical-design?name=Ethical+Design
  2. /printed-books/design-systems?name=Design+Systems.
Mã:
nhập Liên kết từ 'next/link';const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' },];export default function PrintedBooks() { return printedBooks.map((printedBook) => ( 
[*]  {printedBook.name}  ));}
Nếu bạn bao gồm một phân đoạn động trong pathname, thì bạn cũng phải bao gồm nó như một thuộc tính trong đối tượng truy vấn để đảm bảo truy vấn được nội suy trong pathname:
Mã:
import Link from 'next/link';const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' },];// Trong trường hợp này, phân đoạn động `[book-id]` trong pathname// ánh xạ trực tiếp đến tham số truy vấn `book-id`export default function PrintedBooks() { return printedBooks.map((printedBook) => (  {printedBook.name}  ));}
Ví dụ trên có các đường dẫn:
  1. /printed-books/ethical-design
  2. /printed-books/design-systems.
Nếu bạn kiểm tra thuộc tính href trong VSCode, bạn sẽ tìm thấy loại LinkProps, với thuộc tính href là loại Url, có thể là string hoặc UrlObject như đã đề cập trước đó.



Kiểm tra UrlObject dẫn đến giao diện với các thuộc tính:



Bạn có thể tìm hiểu thêm về các thuộc tính này trong tài liệu mô-đun URL của Node.js.

Một trường hợp sử dụng hàm băm là liên kết đến các phần cụ thể trong một trang.
Mã:
nhập Liên kết từ 'next/link';const printedBooks = [{ name: 'Thiết kế đạo đức', id: 'thiết kế đạo đức' }];export default function PrintedBooks() { return printedBooks.map((printedBook) => ( 
[*]  {printedBook.name}  ));}
Siêu liên kết sẽ giải quyết thành /printed-books/ethical-design#faq.
“Tìm hiểu thêm trong tài liệu.”

API next/router

Nếu next/link là khai báo, thì next/router là bắt buộc. Nó hiển thị một hook useRouter cho phép truy cập vào đối tượng router bên trong bất kỳ thành phần hàm nào. Bạn có thể sử dụng hook này để thực hiện định tuyến thủ công, đặc biệt là trong một số trường hợp nhất định khi next/link không đủ hoặc khi bạn cần "hook" vào định tuyến.
Mã:
import { useRouter } from 'next/router';export default function Home() { const router = useRouter(); function handleClick(e) { e.preventDefault(); router.push(href); } return ( Click me )}
useRouter là một hook của React và không thể sử dụng với các lớp. Cần đối tượng router trong các thành phần lớp? Sử dụng withRouter.
Mã:
import { withRouter } from 'next/router';function Home({router}) { function handleClick(e) { e.preventDefault(); router.push(href); } return ( Click me )}export default withRouter(Home);

Đối tượng router

Cả hook useRouter và thành phần bậc cao withRouter đều trả về một đối tượng router với các thuộc tính như pathname, query, asPathbasePath cung cấp cho bạn thông tin về trạng thái URL của trang hiện tại, locale, localesdefaultLocale cung cấp thông tin về ngôn ngữ mặc định đang hoạt động, được hỗ trợ hoặc hiện tại.

Đối tượng router cũng có các phương thức như push để điều hướng đến một URL mới bằng cách thêm một Mục nhập URL vào ngăn xếp lịch sử, replace, tương tự như push nhưng thay thế URL hiện tại thay vì thêm mục nhập URL mới vào ngăn xếp lịch sử.

Tìm hiểu thêm về đối tượng router.

Cấu hình tuyến tùy chỉnh với next.config.js

Đây là một mô-đun Node.js thông thường có thể được sử dụng để cấu hình một số hành vi Next.js nhất định.
Mã:
module.exports = { // tùy chọn cấu hình}
“Nhớ khởi động lại máy chủ của bạn bất cứ khi nào bạn cập nhật next.config.js. Tìm hiểu thêm.”

Đường dẫn cơ sở​

Có đề cập rằng tuyến đường ban đầu/mặc định trong Next.js là pages/index.js với đường dẫn /. Điều này có thể định cấu hình và bạn có thể biến tuyến đường mặc định của mình thành đường dẫn phụ của miền.
Mã:
module.exports = { // đường dẫn mặc định cũ: / // đường dẫn mặc định mới: /dashboard basePath: '/dashboard',};
Những thay đổi này sẽ tự động có hiệu lực trong ứng dụng của bạn với tất cả các đường dẫn / được định tuyến đến /dashboard.
“Tính năng này chỉ có thể sử dụng với Next.js 9.5 trở lên. Tìm hiểu thêm.”

Dấu gạch chéo theo sau​

Theo mặc định, dấu gạch chéo theo sau sẽ không khả dụng ở cuối mỗi URL. Tuy nhiên, bạn có thể chuyển đổi bằng cách:
Mã:
module.exports = { trailingSlash: true};
Mã:
# trailingSlash: false/printed-books/ethical-design#faq# trailingSlash: true/printed-books/ethical-design/#faq
Cả đường dẫn cơ sởcác tính năng trailing slash chỉ có thể sử dụng với Next.js 9.5 trở lên.

Kết luận​

Định tuyến là một trong những phần quan trọng nhất của ứng dụng Next.js của bạn và nó phản ánh trong bộ định tuyến dựa trên hệ thống tệp được xây dựng trên khái niệm về các trang. Các trang có thể được sử dụng để xác định các mẫu định tuyến phổ biến nhất. Các khái niệm về định tuyến và kết xuất có liên quan chặt chẽ với nhau. Hãy áp dụng các bài học trong bài viết này khi bạn xây dựng ứng dụng Next.js của riêng mình hoặc làm việc trên cơ sở mã Next.js. Và hãy xem các tài nguyên bên dưới để tìm hiểu thêm.

Tài nguyên liên quan​

Đọc thêm​

  • Giới thiệu về khả năng kết hợp toàn bộ ngăn xếp
  • Tạo số ngẫu nhiên duy nhất trong JavaScript bằng cách sử dụng các tập hợp
  • GraphQL toàn bộ ngăn xếp với Next.js, Neo4j AuraDB và Vercel
  • Cách trở thành diễn giả giỏi hơn tại các hội nghị
 
Back
Bên trên