next.js之getStaticProps?getStaticPaths使用技巧解析
引言
之前講過(guò) next.js
中的 getServerSideProps
,今天來(lái)講一講另一個(gè)很類(lèi)似的 API
:getStaticProps
,以及和 getStaticProps
緊密相關(guān)的 getStaticPaths
。
getStaticProps
主要用于構(gòu)建時(shí)落地一些靜態(tài)數(shù)據(jù),但不同于 getServerSideProps
,getStaticProps
默認(rèn)情況下只會(huì)在構(gòu)建時(shí)執(zhí)行一次,之后的每次請(qǐng)求都會(huì)使用構(gòu)建時(shí)的數(shù)據(jù)。在 ISR
、SSG
等場(chǎng)景下還有不同的表現(xiàn)。
而 getStaticPaths
則用于配合 getServerSideProps
實(shí)現(xiàn)動(dòng)態(tài)路由的構(gòu)建,next.js
會(huì)在構(gòu)建時(shí)根據(jù) getStaticPaths
的返回值來(lái)生成對(duì)應(yīng)的靜態(tài)頁(yè)面。
使用
先看下 getStaticProps
如何使用,其實(shí)和 getServerSideProps
用法差不多:
export default function GetStaticProps({ content }: { content: string }) { return ( <div> <header>getStaticProps</header> <main>{content}</main> </div> ); } export const getStaticProps = async () => { const content = 'Hello World'; console.log('call getStaticProps'); return { props: { content } }; };
只需要在 page
中導(dǎo)出 getStaticProps
函數(shù),然后在函數(shù)中返回 props
即可。在 page
渲染組件中就可以直接通過(guò) props
即可獲得數(shù)據(jù)。
調(diào)用時(shí)機(jī)
再來(lái)看下 getStaticProps
的調(diào)用時(shí)機(jī),這里和 getServerSideProps
存在很大差異:
- 當(dāng)執(zhí)行
next build
時(shí) - 當(dāng)
getStaticPaths
返回fallback
不為false
時(shí) - 當(dāng)使用了
revalidate
時(shí)
上面給出的例子是 getStaticProps
最簡(jiǎn)單的一個(gè)例子,只有在執(zhí)行 next build
時(shí)才會(huì)調(diào)用 getStaticProps
,之后的每次請(qǐng)求都會(huì)使用構(gòu)建時(shí)的數(shù)據(jù)。
構(gòu)建時(shí) next.js
會(huì)將其構(gòu)建為 html
,并且還會(huì)構(gòu)建一份 json
文件,存儲(chǔ) getStaticProps
的返回值,在訪問(wèn)時(shí)初次進(jìn)入頁(yè)面為該頁(yè)面時(shí)會(huì)直接使用 html
內(nèi)容,而非初次進(jìn)入則會(huì)去請(qǐng)求該 json
文件獲取數(shù)據(jù)進(jìn)行渲染。
json
文件中的數(shù)據(jù)如下:
{ "pageProps": { "content": "Hello World" }, "__N_SSG": true }
可以看到和之前講到的 getServerSideProps
的返回值是基本一致的,只是將 __N_SSP
參數(shù)變更為 __N_SSG
,用以區(qū)分兩個(gè)數(shù)據(jù)的類(lèi)型。
開(kāi)發(fā)時(shí)的 getStaticProps
需要注意的是,在開(kāi)發(fā)時(shí)也就是 next dev
時(shí),getStaticProps
會(huì)在每次頁(yè)面訪問(wèn)時(shí)被請(qǐng)求,也就是和 getServerSideProps
行為基本一致,剛上手時(shí)很容易對(duì)這里感到困惑。
使用 getStaticPaths
getStaticPaths
主要用于動(dòng)態(tài)路由中的靜態(tài)頁(yè)面構(gòu)建,簡(jiǎn)單說(shuō)就是將一個(gè)動(dòng)態(tài)路由通過(guò) getStaticPaths
轉(zhuǎn)換為多個(gè)靜態(tài)頁(yè)面。
下面看下一個(gè)簡(jiǎn)單的例子:
pages/get-static-paths/[id].tsx
function GetStaticPaths({ post }: { post: string }) { return ( <div> <h1>Post: {post}</h1> </div> ); } export async function getStaticPaths() { const paths = new Array(10).fill(0).map((_, i) => ({ params: { id: i + 1 + '' } })); console.log('paths', paths); return { paths, fallback: true }; } export async function getStaticProps({ params }: { params: { id: string } }) { console.log('params', params); return { props: { post: `post ${params.id}` } }; } export default GetStaticPaths;
此處是一個(gè)簡(jiǎn)單的動(dòng)態(tài)路由,通過(guò) getStaticPaths
我們可以定義該動(dòng)態(tài)路由的匹配的路由值,通過(guò) paths[number]
中的 params
參數(shù)和動(dòng)態(tài)路由中的參數(shù)進(jìn)行匹配。以下是 next.js
將其轉(zhuǎn)換為靜態(tài)頁(yè)面的步驟中 getStaticPaths
和 getStaticProps
相關(guān)的部分。
- 調(diào)用
next build
命令,next.js
會(huì)進(jìn)行頁(yè)面數(shù)據(jù)的收集,檢測(cè)到動(dòng)態(tài)路由時(shí)會(huì)嘗試調(diào)用getStaticPaths
并獲取其返回值。 - 將返回值中的
paths
進(jìn)行遍歷,依次取出和動(dòng)態(tài)路由進(jìn)行匹配,匹配后進(jìn)行靜態(tài)頁(yè)面的生成步驟。 - 將
path
中的params
傳入getStaticProps
中,執(zhí)行getStaticProps
獲取返回值。 - 通過(guò)返回值生成相應(yīng)的
html
和json
文件
所以上述代碼我們?cè)?nbsp;next build
時(shí)將會(huì)生成 10 個(gè)靜態(tài)頁(yè)面 [1-10].html
和 10 個(gè) JSON
文件 [1-10].json
,生成的文件可以到 .next/server/pages/
下查看。
fallback
此外上面的 DEMO
中可以看到 fallback
參數(shù),fallback
其實(shí)有三個(gè)可選值:true
、false
和 blocking
,主要是用于控制訪問(wèn)動(dòng)態(tài)路由時(shí)該地址未落地成靜態(tài)頁(yè)面時(shí)的處理。
false
時(shí)基本就只有上述行為,當(dāng)訪問(wèn)不存在的頁(yè)面時(shí)會(huì)返回 404 頁(yè)面,比如上面訪問(wèn)到 /get-static-paths/11
時(shí)會(huì)返回 404。
而 fallback
為 true
時(shí)會(huì)有一些不同,當(dāng)訪問(wèn)不存在的頁(yè)面時(shí)不會(huì)返回 404,而是會(huì)返回動(dòng)態(tài)路由頁(yè)面,并且使用頁(yè)面參數(shù)去請(qǐng)求 getStaticProps
數(shù)據(jù),然后生成靜態(tài)頁(yè)面和 JSON
文件并將 JSON
文件返回動(dòng)態(tài)渲染到頁(yè)面中。而二次訪問(wèn)該頁(yè)面時(shí)由于已經(jīng)有了靜態(tài)頁(yè)面,就和其他已存在頁(yè)面行為一致了??梢岳斫鉃橐环N lazy build
。
fallback
為 blocking
時(shí)行為和 true
基本一致,但不同的是當(dāng)訪問(wèn)不存在的頁(yè)面時(shí)會(huì)等待 getStaticProps
執(zhí)行完成后再返回頁(yè)面,不需要進(jìn)行二次數(shù)據(jù)請(qǐng)求。所以初次訪問(wèn)表現(xiàn)不一致,一個(gè)為異步一個(gè)為同步。
注意點(diǎn)
這里還有一個(gè)比較需要關(guān)注的問(wèn)題是 getStaticPaths
中的 params
中的參數(shù)需要為字符串,否則將會(huì)導(dǎo)致無(wú)法匹配,猜測(cè)為 next.js
中進(jìn)行了類(lèi)型判斷或 map
操作,這個(gè)在后續(xù)源碼分析中細(xì)看。
此外和 getStaticProps
一樣,在開(kāi)發(fā)環(huán)境下 getStaticPaths
也會(huì)在每次訪問(wèn)時(shí)被調(diào)用。
和 getServerSideProps
需要注意 getStaticProps
和 getServerSideProps
無(wú)法混用,在 next.js
的定位中,getStaticProps
主要用于 SSG
場(chǎng)景,而 getServerSideProps
主要用于 SSR
場(chǎng)景,在同一頁(yè)面中使用時(shí)將會(huì)提示:You can not use getStaticProps or getStaticPaths with getServerSideProps. To use SSG, please remove getServerSideProps
。
當(dāng)然,個(gè)人覺(jué)得從設(shè)計(jì)上進(jìn)行混用也沒(méi)啥問(wèn)題,getStaticProps
落地靜態(tài)數(shù)據(jù)、getServerSideProps
落地動(dòng)態(tài)數(shù)據(jù),然后動(dòng)態(tài)覆蓋靜態(tài)即可,next.js
這么設(shè)計(jì)可能是為了遵循單一職能原則。
總結(jié)
最后來(lái)聊一聊什么場(chǎng)景下我們應(yīng)該使用 getStaticProps
,其實(shí)官方使用文檔里有列出推薦的使用場(chǎng)景,我這邊說(shuō)下自己的想法:如果頁(yè)面中的數(shù)據(jù)是通過(guò)發(fā)布行為來(lái)進(jìn)行更新的,那么就可以使用 getStaticProps
。當(dāng)然,要注意數(shù)據(jù)的安全性等問(wèn)題。如果遇到頁(yè)面中既有動(dòng)態(tài)數(shù)據(jù)又有靜態(tài)數(shù)據(jù),那還是老老實(shí)實(shí)使用 getServerSideProps
吧。
當(dāng)然,有同學(xué)可能發(fā)現(xiàn)上面只講了兩種 getStaticProps
的場(chǎng)景,而 revalidate
的場(chǎng)景沒(méi)講到,由于 revalidate
和 ISR
相關(guān),這個(gè)后面再說(shuō)(下次一定,逃~)。
以上就是next.js之getStaticProps getStaticPaths使用技巧解析的詳細(xì)內(nèi)容,更多關(guān)于next.js getStaticProps getStaticPaths的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JS實(shí)現(xiàn)鼠標(biāo)箭頭變成一個(gè)燃燒燭光效果的方法
這篇文章主要介紹了JS實(shí)現(xiàn)鼠標(biāo)箭頭變成一個(gè)燃燒燭光效果的方法,實(shí)例分析了javascript操作鼠標(biāo)事件及圖片的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02微信小程序+mqtt,esp8266溫濕度讀取的實(shí)現(xiàn)方法
這篇文章主要介紹了微信小程序+mqtt,esp8266溫濕度讀取的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04JS實(shí)現(xiàn)的點(diǎn)擊按鈕圖片上下滾動(dòng)效果示例
這篇文章主要介紹了JS實(shí)現(xiàn)的點(diǎn)擊按鈕圖片上下滾動(dòng)效果,涉及javascript事件響應(yīng)及頁(yè)面元素屬性動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-01-01javascript實(shí)現(xiàn)dom動(dòng)態(tài)創(chuàng)建省市縱向列表菜單的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)dom動(dòng)態(tài)創(chuàng)建省市縱向列表菜單的方法,可實(shí)現(xiàn)省市列表菜單效果,涉及javascript鼠標(biāo)事件及頁(yè)面處理json數(shù)據(jù)的技巧,需要的朋友可以參考下2015-05-05javascript引擎長(zhǎng)時(shí)間獨(dú)占線程造成卡頓的解決方案
這篇文章主要介紹了javascript引擎長(zhǎng)時(shí)間獨(dú)占線程造成卡頓的解決方案,需要的朋友可以參考下2014-12-12JS網(wǎng)頁(yè)播放聲音實(shí)現(xiàn)代碼兼容各種瀏覽器
JS網(wǎng)頁(yè)播放聲音有多種方法可以實(shí)現(xiàn),不過(guò)兼容各種瀏覽器的就沒(méi)有幾個(gè)了,不過(guò)本文的這個(gè)示例或許對(duì)大家有所幫助2013-09-09