/

透過 getInitialProps 在 Next.js 組件中提供數據

透過 getInitialProps 在 Next.js 組件中提供數據

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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。

首先,我們為組件命名:

1
2
3
4
5
const Post = () => {
//...
}

export default Post

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

1
2
3
4
5
6
7
8
9
const Post = () => {
//...
}

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

export default Post

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

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

1
2
3
Post.getInitialProps = ({ query }) => {
//...
}

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

1
2
3
4
5
Post.getInitialProps = ({ query }) => {
return {
post: posts[query.id]
}
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 對象將會很熟悉。