術(shù)與器:React 服務(wù)端渲染和靜態(tài)站點(diǎn)生成
嗨,我是你別人放假我不放、依然堅(jiān)持努力更新的勾勾/(ㄒoㄒ)/。

回憶一下上兩篇內(nèi)容:
《術(shù)與器:Next.js 框架的基本應(yīng)用》
本篇繼續(xù)術(shù)、器層面,即 Next.js 的服務(wù)端渲染和靜態(tài)站點(diǎn)生成解決方案。
服務(wù)端渲染方法
getServerSideProps() 這個(gè)方法是服務(wù)端渲染的方法,適合頁(yè)面數(shù)據(jù)實(shí)時(shí)變化的應(yīng)用。getServerSideProps() 方法接收一個(gè)參數(shù),是當(dāng)前的 HTTP 客戶端請(qǐng)求對(duì)象。
import React from 'react'// 類組件class ListPage extends React.Component {render(){return <div><h3 >ListPageh3><h4>服務(wù)器數(shù)據(jù):h4>{/* 類組件的方式展示數(shù)據(jù)內(nèi)容 */}<p> {this.props.data[0].name} p>div>}}// // 函數(shù)組件// function ListPage({data}){// return (////ListPage
//服務(wù)器數(shù)據(jù):
// {/* 類組件的方式展示數(shù)據(jù)內(nèi)容 */}//{data[1].name}
//// )// }// Node 環(huán)境下執(zhí)行// 文件讀寫(xiě),數(shù)據(jù)庫(kù)鏈接,網(wǎng)絡(luò)通信// export async function getStaticProps(){export async function getServerSideProps(){const res = await fetch('http://localhost:80/');const backData = await res.json();const data = JSON.parse(backData);console.log(data);return {props:{data}}}export default ListPage
項(xiàng)目構(gòu)建與運(yùn)行
項(xiàng)目構(gòu)建:npm ?run ?build
啟動(dòng)運(yùn)行項(xiàng)目: ?npm run start
靜態(tài)站點(diǎn)生成
Next.js 不僅提供服務(wù)端渲染的方式,同時(shí)還提供了靜態(tài)站點(diǎn)生成的解決方案。
靜態(tài)站點(diǎn)生成也被稱為 SSG(Static Site Generators),就是將應(yīng)用中用到的所以頁(yè)面,全部生成靜態(tài)文件的方案。
next 官方建議在大多數(shù)情況下使用靜態(tài)站點(diǎn)生成,靜態(tài)站點(diǎn)生成方案,更適合 CDN、緩存、內(nèi)容數(shù)據(jù)無(wú)變化的頁(yè)面,比如:宣傳頁(yè)、博客文章、幫助文檔、新聞頁(yè)面、電商產(chǎn)品列表等眾多應(yīng)用場(chǎng)景。
Next.js ?中的?getStaticProps、getStaticPaths?就是靜態(tài)站點(diǎn)生成,是在構(gòu)建時(shí)生成 HTML 的方法,以后的每個(gè)請(qǐng)求都共用構(gòu)建時(shí)生成好的 HTML。
Next.js 建議大多數(shù)頁(yè)面使用靜態(tài)生成,因?yàn)轫?yè)面都是事先生成好的,一次構(gòu)建,反復(fù)使用,訪問(wèn)速度快。服務(wù)器端渲染訪問(wèn)速度不如靜態(tài)生成快,但是由于每次請(qǐng)求都會(huì)重新渲染,所以適用數(shù)據(jù)頻繁更新的頁(yè)面或頁(yè)面內(nèi)容隨請(qǐng)求變化而變化的頁(yè)面。
在 next.js 中,靜態(tài)生成分為無(wú)數(shù)據(jù)和有數(shù)據(jù)兩種情況。如果組件不需要在其他地方獲取數(shù)據(jù),默認(rèn)直接進(jìn)行靜態(tài)生成;如果組件需要在其他地方獲取數(shù)據(jù),在構(gòu)建時(shí) Next.js 會(huì)預(yù)先獲取組件需要的數(shù)據(jù),然后再對(duì)組件進(jìn)行靜態(tài)生成。
我們來(lái)對(duì)比一下,開(kāi)發(fā)環(huán)境不會(huì)打包靜態(tài)文件,生產(chǎn)環(huán)境打包,默認(rèn)生成靜態(tài)文件。

那么,有數(shù)據(jù)的情況應(yīng)該怎么做呢?
有數(shù)據(jù)的靜態(tài)生成
getStaticProps() 這個(gè)方法官方翻譯為靜態(tài)生成,是把組件提前編譯成 html 文件,然后把整個(gè) html 文件響應(yīng)到客戶端,從而達(dá)到預(yù)渲染的目的。
getStaticProps() ?方法是個(gè)異步方法,在 Node 環(huán)境下執(zhí)行(構(gòu)建時(shí)執(zhí)行),因此可以進(jìn)行文件讀寫(xiě)、數(shù)據(jù)庫(kù)鏈接、網(wǎng)絡(luò)通信等一些列操作。
對(duì)于這個(gè)方法的使用,先看 demo:
import React from 'react'import Axios from "axios"// 類組件class ListPage extends React.Component {render(){return <div><h3 >ListPageh3><h4>服務(wù)器數(shù)據(jù):h4>{/* 類組件的方式展示數(shù)據(jù)內(nèi)容 */}<p> {this.props.data[0].name} p>div>}}// // 函數(shù)組件// function ListPage({data}){// return (////ListPage
//服務(wù)器數(shù)據(jù):
// {/* 類組件的方式展示數(shù)據(jù)內(nèi)容 */}//{data[1].name}
//// )// }// Node 環(huán)境下執(zhí)行// 文件讀寫(xiě),數(shù)據(jù)庫(kù)鏈接,網(wǎng)絡(luò)通信export async function getStaticProps(){const d3 = await Axios.get('http://localhost:80/');const data = JSON.parse(d3.data);console.log(data)// 返回的 Props 屬性的值會(huì)傳遞給組件return {props:{data}}}export default ListPage
getStaticProps 方法內(nèi)部必須返回一個(gè)對(duì)象,這個(gè)對(duì)象中的 props 屬性將傳遞到組件中。
getStaticPaths() ?這個(gè)方法也是靜態(tài)生成。與 getStaticProps 共同使用,會(huì)根據(jù)不同的請(qǐng)求參數(shù)生成不同的靜態(tài)頁(yè)面。
它的使用方式比較特殊,代碼文件要放在一個(gè)目錄中。同時(shí)代碼文件的文件名,要使用可選項(xiàng) ?文件名的形式,如?\pages\props\[id].js 的形式。在項(xiàng)目構(gòu)建時(shí),next 會(huì)根據(jù)不同的 ID 值,生成不同的對(duì)應(yīng)的 靜態(tài)文件,如下代碼:
import React from 'react'import Axios from "axios"// 類組件class ListPage extends React.Component {render() {return <div><h3 >ListPage - Classh3><p>{this.props.backData.name}p>div>}}// 根據(jù)客戶端參數(shù)生成靜態(tài)頁(yè)面export async function getStaticPaths() {return {// 匹配客戶端請(qǐng)求的 id 值paths: [{ params: { id: "1" } }, { params: { id: "2" } }],fallback: false}}// 自動(dòng)調(diào)用當(dāng)前方法,將客戶端參數(shù)傳入; { params } 接受到的客戶端參數(shù)export async function getStaticProps({ params }) {const d3 = await Axios.get('http://localhost:80/');const data = JSON.parse(d3.data);console.log(params)// 循環(huán)服務(wù)器數(shù)據(jù),獲取for (let i = 0; i < data.length; i++) {// console.log(data[i].id)if (params.id == data[i].id) {// 返回對(duì)應(yīng)數(shù)據(jù)const backData = data[i];return {props: { backData }}}}}export default ListPage
最終構(gòu)建后,會(huì)生成不同的靜態(tài)頁(yè)面:

靜態(tài)站點(diǎn)導(dǎo)出
"scripts": {"dev": "next dev","build": "next build","start": "next start","export": "next build && next export"},
執(zhí)行命令 npm run export,進(jìn)行構(gòu)建和導(dǎo)出操作,生成 out 文件夾,獲取靜態(tài)站點(diǎn)資源。
除此之外,還有專門(mén)針對(duì) React 的 SSG 靜態(tài)站點(diǎn)生成方案:Gatsby https://www.gatsbyjs.cn/ ,感興趣的可以自己去看看。
當(dāng)然,你 React 有的,我 Vue 怎么可能沒(méi)有呢:Gridsome ?https://www.gridsome.cn/
斗爭(zhēng)吧,前端框架們......
推薦閱讀:
術(shù)與器:Next.js 框架的基本應(yīng)用
點(diǎn)點(diǎn)“贊”和“在看”,保護(hù)頭發(fā),減少bug。
