如何使用 getInitialProps 在 Next.js 組件中提供數據

在我們談到在 Next.js 中添加動態內容時,我們遇到了一個問題,即動態生成頁面所需的數據無法事先獲取,當我們試圖從 JSON 文件中獲取數據時:

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>
 </>
 )
}

我們收到了以下錯誤信息:

我們如何解決這個問題?又該如何使 SSR 適用於動態路由?

我們需要使用一個名為 getInitialProps() 的特殊函數來為組件提供 props。

首先,我們為組件命名:

const Post = () => {
 //...
}

export default Post

然後我們將函數添加到其中:

const Post = () => {
 //...
}

Post.getInitialProps = () => {
 //...
}

export default Post

這個函數接受一個對象作為參數,其中包含多個屬性。我們目前感興趣的事情是,我們可以獲取之前用於獲取帖子 ID 的 query 對象。

因此,我們可以使用“對象解構賦值”語法獲取它:

Post.getInitialProps = ({ query }) => {
 //...
}

現在我們可以從此函數返回帖子:

Post.getInitialProps = ({ query }) => {
 return {
 post: posts[query.id]
 }
}

同時,我們可以刪除對 useRouter 的引入語句,然後通過傳遞給 Post 組件的 props 屬性獲取帖子:

import posts from '../../posts.json'

const Post = props => {
 return (
 <div>
 <h1>{props.post.title}</h1>
 <p>{props.post.content}</p>
 </div>
 )
}

Post.getInitialProps = ({ query }) => {
 return {
 post: posts[query.id]
 }
}

export default Post

現在不會再出現錯誤,並且 SSR 將按預期工作,可以通過檢查瀏覽器的“查看源代碼”查看效果:

getInitialProps 函數將在服務器端執行,也將在客戶端執行,例如通過使用 Link 組件導航到新頁面。

值得注意的是,在接收到的上下文對象中,getInitialProps 除了 query 對象外,還會收到以下屬性:

  • pathname:URL 的 path 部分
  • asPath:在瀏覽器中顯示的實際路徑(包括查詢)的字符串

例如,通過調用 http://localhost:3000/blog/test,它們分別對應為:

  • /blog/[id]
  • /blog/test

在服務器端渲染的情況下,它還將收到以下參數:

  • req:HTTP 請求對象
  • res:HTTP 響應對象
  • err:錯誤對象

如果您有任何 Node.js 編程經驗,那麼 reqres 對象將會很熟悉。