如何使用 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 編程經驗,那麼 req
和 res
對象將會很熟悉。