next.js - SSR
SSR, server side rendering.
CSR vs SSR vs SSG
CSR (Client Side Rendering)
網頁起始無內容,在網頁 mounted 後才取得內容。故SEO無效因為搜尋引擎看不到商品目錄。
適合資訊不公開等保密性較高的應用。
SSR (Server Side Rendering)
於 request 時決定了網頁起始內容。SEO有效。網頁內容在操作後可變動,即商品目錄可下查詢條件而變動。
適合有商品目錄類的應用。
SSG (Static Side Generation)
於 build/bundle 時期決定了內容,產出全靜態網站。SEO有效。因為是靜態屬性所以內容無法變更,即商品目錄無法變動頂多隱藏或顯示。
適合海報、廣告類的應用。
getServerSideProps
getServerSideProps
重點整理
getServerSideProps
重點整理Next.js
的SSR能力是透過此函式getServerSideProps
實作。下面列出幾個要點:
此函式只會在 Server Side 執行。
此函式內的內容不會送到前端。
此函式可以取用後端全部資源,包含後端檔案讀寫與DB Access。
此函式只在網頁 "page" 進入點有效。如:
pages/index.tsx
。此函式在每次 request 都會觸發。
程式碼紀錄
import type { NextPage } from 'next'
import type { Commodity } from './interfaces'
import Head from 'next/head'
import AppForm from './AppForm'
import { qryCommodityList } from './bizLogic'
const DM0010Page: NextPage<{
commodityList: Commodity[] // 商品目錄將從 props 送進來。
}> = (props) => {
return (
<>
<Head>
<title>DM0010</title>
<link rel="icon" href="/favicon.ico" />
</Head>
{/* 將商品目錄往子層送進去 */}
<AppForm {...props} />
</>
)
}
export default DM0010Page
/// SSR with dynamic parameters
/// 此函式只在 page 進入點有效。
export async function getServerSideProps(context) {
// 解析URL Query參數:http://localhost:3000/demo/dm0010?category=運動
const { query: { category } } = context
// 查詢商品目錄
const commodityList = qryCommodityList(category)
// 商品目錄將從 props 送進去。
return {
props: {
commodityList
}
}
}
import type { Commodity } from './interfaces'
import { useState } from 'react'
import { qryCommodityList } from './bizLogic'
export default (props: {
commodityList: Commodity[] // 初始商品目錄將從props送進來。
}) => {
// 初始商品目錄來自SSR模式,從props送進來。
const [commodityList, setCommodityList] = useState<Commodity[]>(props.commodityList)
// 之後操作查詢商品目錄來自CSR模式。
function handleQuery() {
const commodityList = qryCommodityList('other')
setCommodityList(commodityList)
}
return (
<div>
<h1>DM0010: SSR 練習</h1>
<button onClick={handleQuery}>查詢</button>
<h2>模擬商品清單</h2>
<ul>
{Array.isArray(commodityList) && commodityList.map((item, index) => (
<li key={index}>
{`${item.cid}-${item.cname} 數量 ${item.amount} | ${item.category}`}
</li>
))}
</ul>
</div>
)
}
import type { Commodity } from './interfaces'
import db from './db.json'
/// 模擬自DB主機取值
export function qryCommodityList(category: string): Commodity[] {
return db.commodityList.filter(c => !category || c.category === category)
}t
export interface Commodity {
cid: string,
cname: string,
amount: number,
category: string,
}
// 模擬商品目錄
{"commodityList":[
{"cid":"C00","cname":"商品0號","category":"運動","amount":1000},
{"cid":"C01","cname":"商品1號","category":"運動","amount":17},
{"cid":"C02","cname":"商品2號","category":"文書","amount":21},
{"cid":"C03","cname":"商品3號","category":"文書","amount":390},
{"cid":"C04","cname":"商品4號","category":"文書","amount":434},
{"cid":"C05","cname":"商品5號","category":"文書","amount":5},
{"cid":"C06","cname":"商品6號","category":"文書","amount":6},
{"cid":"C07","cname":"商品7號","category":"運動","amount":7},
{"cid":"C08","cname":"商品8號","category":"other","amount":87},
{"cid":"C09","cname":"商品9號","category":"運動","amount":93},
{"cid":"C10","cname":"商品10號","category":"運動","amount":102}
]}
沒圖沒真象
測試網址:http://localhost:3000/demo/dm0010?category=文書
產生畫面如下,簡易的商品清單。

解析產生的 html 碼中可以看到商品目錄訊息,這在CSR模式下是看不到的。

EOF
Last updated