Next.js-獲取資料(getStaticProps)

很重要很重要的東西。

簡述

一個網站通常都會有「抓資料」這個流程,在 React 的世界裡我們通常會用 useEffect 的方式來做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
export default function Index() {
const [data, setData] = useState([])

useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.json())
.then((data) => setData(data))
}, [])

return (
<div>
<h1>All Ninjas</h1>
{data.map((item) => (
<div key={item.id}>
<a className={styles.single}>
<h2>{item.name}</h2>
</a>
</div>
))}
</div>
)
}

這樣子做雖然好像可行,但要注意這樣就變成 CSR 而不是 SSR 了,換句話說就是失去原本的意義了,因為打開原始碼你還是會看到「空蕩蕩的內容」,而不是被渲染後的結果。

所以要讓「抓資料」這件事在 Server 端就完成並且渲染的話,要改用 Next 提供的 getStaticProps,這是其中一種,還有另外一種方式叫做 getServerSideProps,詳細可以參考這篇文章

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// export 一個 getStaticProps 給 Next 做處理(必須是 async 函式)
export const getStaticProps = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/users')
const ninjas = await response.json()

return {
props: {
ninjas
}
}
}

export default function Index(props) {
return (
<div>
<h1>All Ninjas</h1>
{props.ninjas.map((ninja) => (
<div key={ninja.id}>
<a className={styles.single}>
<h2>{ninja.name}</h2>
</a>
</div>
))}
</div>
)
}

背後的原理其實就是告訴 Next 在做 pre-rendering 時先去執行 getStaticProps,接著在把回傳值當作 props 傳給對應的 page 元件,因此 page 只要根據 props 來渲染出內容就行了。

關於 Pre-rendering(SSG / SSR)

剛剛的範例用的是 SSG(Static Side Generation),不過除此之外 Next 還提供了另一種方法是 SSR(Server Side Rendering),這兩者的共通點是「Pre-rendering」,就是畫面都會在 Server 端先渲染完成。

主要的差別在於 Pre-rendering 的「時機點」,SSG 是在 build 時產生,SSR 則是在收到 request 時產生,參考這張圖:

ssr-ssg-overview

附註:如果用 PHP 邏輯來解釋的話 SSG 就像是一開始就先把編譯後的結果存起來,等有 request 時再直接送出去;而 SSR 則是收到 request 時才做編譯。

至於哪一種方式比較好還是要看情況,SSG 比較適合用在內容不太會變動的(畢竟都叫 Static 了),而 SSR 則適合用在內容會常常更新的內容(需要 Server 頻繁的產生新的 HTML),總之要視情境來選擇。

Next.js-動態路由 Next.js-meta 標籤
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×