Nội dung động trong Next.js với bộ định tuyến

Cách thiết lập nội dung động trong trang Next.js

bên trongbài trướcchúng tôi đã thấy cách liên kết trang chủ với trang blog.

Blog là một trường hợp sử dụng tuyệt vời cho Next.js, một trường hợp chúng ta sẽ tiếp tục khám phá trong chương này bằng cách thêmbài đăng trên blog.

Các bài đăng trên blog có một URL động. Ví dụ: một bài đăng có tiêu đề “Xin chào thế giới” có thể có URL/blog/hello-world. Bài đăng có tiêu đề “Bài đăng thứ hai của tôi” có thể có URL/blog/my-second-post.

Nội dung này là động và có thể được lấy từ cơ sở dữ liệu, tệp đánh dấu hoặc hơn thế nữa.

Next.js có thể phân phát nội dung động dựa trênURL động.

Chúng tôi tạo một URL động bằng cách tạo một trang động với[]cú pháp.

Làm sao? Chúng tôi thêm mộtpages/blog/[id].jstập tin. Tệp này sẽ xử lý tất cả các URL động trong/blog/tuyến đường, giống như những tuyến đường mà chúng tôi đã đề cập ở trên:/blog/hello-world,/blog/my-second-postvà hơn thế nữa.

Trong tên tệp,[id]bên trong dấu ngoặc vuông có nghĩa là bất kỳ thứ gì động sẽ được đưa vào bên trongidtham số củathuộc tính truy vấnsau đóbộ định tuyến.

Ok, đó là một chút quá nhiều thứ cùng một lúc.

Cái gìbộ định tuyến?

Bộ định tuyến là một thư viện được cung cấp bởi Next.js.

Chúng tôi nhập nó từnext/router:

import { useRouter } from "next/router";

và một khi chúng ta cóuseRouter, chúng tôi khởi tạo đối tượng bộ định tuyến bằng cách sử dụng:

const router = useRouter();

Khi chúng ta có đối tượng bộ định tuyến này, chúng ta có thể trích xuất thông tin từ nó.

Đặc biệt, chúng tôi có thể lấy phần động của URL trong[id].jstập tin bằng cách truy cậprouter.query.id.

Vì vậy, chúng ta hãy tiếp tục và áp dụng tất cả những điều đó vào thực tế.

Tạo tệppages/blog/[id].js:

import { useRouter } from "next/router";

export default () => { const router = useRouter();

return ( <> <h1>Blog post</h1> <p>Post id: {router.query.id}</p> </> ); };

Bây giờ nếu bạn đi đếnhttp://localhost:3000/blog/testbộ định tuyến, bạn sẽ thấy điều này:

Chúng ta có thể sử dụng cái nàyidtham số để thu thập bài viết từ danh sách các bài viết. Từ một cơ sở dữ liệu, chẳng hạn. Để giữ mọi thứ đơn giản, chúng tôi sẽ thêm mộtposts.jsontệp trong thư mục gốc của dự án:

{
  "test": {
    "title": "test post",
    "content": "Hey some post content"
  },
  "second": {
    "title": "second post",
    "content": "Hey this is the second post content"
  }
}

Bây giờ chúng ta có thể nhập nó và tra cứu bài đăng từidChìa khóa:

import { useRouter } from "next/router";
import posts from "../../posts.json";

export default () => { const router = useRouter();

const post = posts[router.query.id];

return ( <> <h1>{post.title}</h1> <p>{post.content}</p> </> ); };

Tải lại trang sẽ hiển thị cho chúng tôi kết quả này:

Nhưng nó không phải! Thay vào đó, chúng tôi gặp lỗi trong bảng điều khiển và lỗi trong trình duyệt cũng vậy:

Tại sao? Bởi vì .. trong quá trình kết xuất, khi khởi tạo thành phần, dữ liệu vẫn chưa có ở đó. Chúng ta sẽ xem cách cung cấp dữ liệu cho thành phần bằng getInitialProps trong bài học tiếp theo.

Còn bây giờ, hãy thêm một chútif (!post) return <p></p>kiểm tra trước khi trả lại JSX:

import { useRouter } from "next/router";
import posts from "../../posts.json";

export default () => { const router = useRouter();

const post = posts[router.query.id]; if (!post) return <p></p>;

return ( <> <h1>{post.title}</h1> <p>{post.content}</p> </> ); };

Bây giờ mọi thứ sẽ hoạt động. Ban đầu, thành phần được hiển thị mà không có độngrouter.query.idthông tin. Sau khi hiển thị, Next.js kích hoạt cập nhật với giá trị truy vấn và trang hiển thị thông tin chính xác.

Và nếu bạn xem nguồn, nó trống<p>trong HTML:

Chúng tôi sẽ sớm khắc phục sự cố này không triển khai SSR và điều này gây hại cho cả thời gian tải cho người dùng của chúng tôi, SEO và chia sẻ xã hội như chúng ta đã thảo luận.

Chúng tôi có thể hoàn thành ví dụ blog bằng cách liệt kê những bài đăng đó trongpages/blog.js:

import posts from "../posts.json";

const Blog = () => ( <div> <h1>Blog</h1>

<span style="color:#f92672">&lt;</span><span style="color:#a6e22e">ul</span><span style="color:#f92672">&gt;</span>
  {Object.<span style="color:#a6e22e">entries</span>(<span style="color:#a6e22e">posts</span>).<span style="color:#a6e22e">map</span>((<span style="color:#a6e22e">value</span>, <span style="color:#a6e22e">index</span>) =&gt; {
    <span style="color:#66d9ef">return</span> <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">li</span> <span style="color:#a6e22e">key</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">index</span>}<span style="color:#f92672">&gt;</span>{<span style="color:#a6e22e">value</span>[<span style="color:#ae81ff">1</span>].<span style="color:#a6e22e">title</span>}<span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/li&gt;;</span>
  })}
<span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/ul&gt;</span>

</div> );

export default Blog;

Và chúng tôi có thể liên kết chúng với các trang bài đăng riêng lẻ, bằng cách nhậpLinktừnext/linkvà sử dụng nó trong vòng lặp bài viết:

import Link from "next/link";
import posts from "../posts.json";

const Blog = () => ( <div> <h1>Blog</h1>

<span style="color:#f92672">&lt;</span><span style="color:#a6e22e">ul</span><span style="color:#f92672">&gt;</span>
  {Object.<span style="color:#a6e22e">entries</span>(<span style="color:#a6e22e">posts</span>).<span style="color:#a6e22e">map</span>((<span style="color:#a6e22e">value</span>, <span style="color:#a6e22e">index</span>) =&gt; {
    <span style="color:#66d9ef">return</span> (
      <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">li</span> <span style="color:#a6e22e">key</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">index</span>}<span style="color:#f92672">&gt;</span>
        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">Link</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">"/blog/[id]"</span> <span style="color:#a6e22e">as</span><span style="color:#f92672">=</span>{<span style="color:#e6db74">"/blog/"</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">value</span>[<span style="color:#ae81ff">0</span>]}<span style="color:#f92672">&gt;</span>
          <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">a</span><span style="color:#f92672">&gt;</span>{<span style="color:#a6e22e">value</span>[<span style="color:#ae81ff">1</span>].<span style="color:#a6e22e">title</span>}<span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/a&gt;</span>
        <span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/Link&gt;</span>
      <span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/li&gt;</span>
    );
  })}
<span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/ul&gt;</span>

</div> );

export default Blog;

Tải xuống miễn phí của tôiSổ tay Next.js


Thêm các bài hướng dẫn tiếp theo: