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].js
tậ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-post
và 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 trongid
tham 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].js
tậ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/test
bộ định tuyến, bạn sẽ thấy điều này:
Chúng ta có thể sử dụng cái nàyid
tham 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.json
tệ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ừid
Chì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.id
thô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"><</span><span style="color:#a6e22e">ul</span><span style="color:#f92672">></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>) => {
<span style="color:#66d9ef">return</span> <span style="color:#f92672"><</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">></span>{<span style="color:#a6e22e">value</span>[<span style="color:#ae81ff">1</span>].<span style="color:#a6e22e">title</span>}<span style="color:#f92672"><</span><span style="color:#960050;background-color:#1e0010">/li>;</span>
})}
<span style="color:#f92672"><</span><span style="color:#960050;background-color:#1e0010">/ul></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ậpLink
từnext/link
và 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"><</span><span style="color:#a6e22e">ul</span><span style="color:#f92672">></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>) => {
<span style="color:#66d9ef">return</span> (
<span style="color:#f92672"><</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">></span>
<span style="color:#f92672"><</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">></span>
<span style="color:#f92672"><</span><span style="color:#a6e22e">a</span><span style="color:#f92672">></span>{<span style="color:#a6e22e">value</span>[<span style="color:#ae81ff">1</span>].<span style="color:#a6e22e">title</span>}<span style="color:#f92672"><</span><span style="color:#960050;background-color:#1e0010">/a></span>
<span style="color:#f92672"><</span><span style="color:#960050;background-color:#1e0010">/Link></span>
<span style="color:#f92672"><</span><span style="color:#960050;background-color:#1e0010">/li></span>
);
})}
<span style="color:#f92672"><</span><span style="color:#960050;background-color:#1e0010">/ul></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:
- Bắt đầu với Next.js
- Next.js vs Gatsby vs create-react-app
- Cách cài đặt Next.js
- Liên kết hai trang trong Next.js bằng Liên kết
- Nội dung động trong Next.js với bộ định tuyến
- Cung cấp dữ liệu cho thành phần Next.js bằng getInitialProps
- Tạo kiểu cho các thành phần Next.js bằng CSS
- Tìm nạp trước nội dung trong Next.js
- Sử dụng bộ định tuyến để phát hiện liên kết hoạt động trong Next.js
- Xem nguồn để xác nhận SSR đang hoạt động trong Next.js
- Next.js: điền thẻ head bằng các thẻ tùy chỉnh
- Triển khai ứng dụng Next.js ngay bây giờ
- Next.js: chỉ chạy mã ở phía máy chủ hoặc phía máy khách trong Next.js
- Triển khai ứng dụng Next.js trong phiên bản sản xuất
- Cách phân tích các gói ứng dụng Next.js
- Các mô-đun tải chậm trong Next.js
- Thêm thành phần trình bao bọc vào ứng dụng Next.js của bạn
- Các biểu tượng được Next.js thêm vào ứng dụng của bạn
- Gói ứng dụng Next.js
- Cách sử dụng Bộ định tuyến Next.js
- Cách sử dụng các tuyến API Next.js
- Cách lấy cookie phía máy chủ trong ứng dụng Next.js
- Cách thay đổi cổng ứng dụng Next.js