在 Next.js 中使用路由器設置動態內容
如何在 Next.js 網站中設置動態內容?
在使用 Link 在 Next.js 中連接兩個頁面文章中,我們看到了如何將主頁連接到博客頁面。
博客是 Next.js 的一個很好的用例,我們將在本章中繼續探索,並添加博客文章。
博客文章有動態的 URL,例如標題為“Hello World”的文章可能具有 URL /blog/hello-world
,標題為“我的第二篇文章”的文章可能具有 URL /blog/my-second-post
。
這些內容是動態的,可能來自數據庫、markdown 文件或其他來源。
Next.js 可以根據動態 URL 提供動態內容。
我們可以通過使用 []
語法創建動態 URL。
如何做到這一點呢?我們添加一個 pages/blog/[id].js
文件。此文件將處理所有 /blog/
路由下的動態 URL,例如上面提到的 /blog/hello-world
、/blog/my-second-post
等。
在文件名中,方括號中的[id]
表示任何動態的內容將放在路由器的查詢屬性的id參數中。
好的,一次介紹了這麼多東西。
什麼是路由器(router)?
路由器是 Next.js 提供的一個庫。
我們從 next/router
導入它:
1 | import { useRouter } from "next/router"; |
一旦我們有了 useRouter
,我們可以使用以下代碼來實例化路由器對象:
1 | const router = useRouter(); |
一旦我們有了這個路由器對象,我們可以從中提取信息。
特別是我們可以通過訪問 [id].js
文件中的 router.query.id
來獲取 URL 的動態部分。
讓我們繼續實踐這些事情。
創建文件 pages/blog/[id].js
:
1 | import { useRouter } from "next/router"; |
現在,如果您轉到 http://localhost:3000/blog/test
,您應該會看到以下內容:
我們可以使用此 id
參數從一個文章列表中獲取文章。例如,可以從數據庫獲取文章。為了保持簡單,我們將在項目根目錄中添加一個 posts.json
文件:
1 | { |
現在,我們可以導入它並根據 id
鍵查找文章:
1 | import { useRouter } from "next/router"; |
重新載入頁面應該顯示正確的結果:
但並沒有!相反,我們在控制檯上和瀏覽器中都收到了一個錯誤:
為什麼?因為..在渲染過程中,當組件被初始化時,數據還沒有準備好。我們將在下一節中看到如何使用 getInitialProps
將數據提供給組件。
現在,在返回 JSX 之前,添加一個小小的 if (!post) return <p></p>
檢查:
1 | import { useRouter } from "next/router"; |
現在應該可以正常工作了。最初,該組件在沒有動態的 router.query.id
信息的情況下被渲染。渲染完成後,Next.js 會根據查詢的值觸發更新,並且頁面會顯示正確的信息。
並且,如果您檢視源代碼,HTML 中會有一個空的 <p>
標記:
我們很快將解決這個問題,該問題導致無法實現服務器端渲染(SSR),這對於我們的用戶來說,加載時間、SEO 和社交分享都是有害的,正如我們之前討論的那樣。
我們可以通過在 pages/blog.js
中列出那些文章來完善博客示例:
1 | import posts from "../posts.json"; |
我們可以通過導入 next/link
並在文章循環中使用它將它們鏈接到個別的博客文章頁面:
1 | import Link from "next/link"; |
tags: [“Next.js”, “路由器 (router)”, “動態內容 (dynamic content)”, “數據庫 (database)”, “markdown 文件”]