type
status
date
slug
summary
tags
category
icon
password

🔖 Next.js 介紹

✒️ 前言

Next.js 無需配置即可讓你快速創建 SEO React Apps。
傳統的 React 應用在瀏覽器啟動時,使用一個無任何渲染內容的 HTML 頁面外殼再 客戶端渲染(Client Side Rendering),而瀏覽器會獲取包含 React 代碼以渲染內容到頁面,並使其交互的 JavaScript 文件。
notion image
但是客戶端渲染有兩個主要缺點:
一來是內容無法可靠地被所有搜索引擎索引,或被社交媒體鏈接的機器人讀取,
notion image
二來是當用戶首次訪問網頁時,首次的內容繪製可能需要更長的時間。
notion image
Next.js 是一個框架,可以讓您構建 React 應用,但會在服務器上預先渲染內容。因此用戶或搜索機器人在接收到此初始頁面後,首次看到的即是完全渲染的 HTML。
notion image
notion image
notion image
notion image
然後再由客戶端渲染接管,工作方式就與傳統的 React 應用一樣。它將兩者的優點結合起來,能為機器人提供完全渲染的內容,並為用戶提供高度交互的內容。

✒️ 路由

在 Next.js 項目中,您有一個 "pages" 目錄,每個 JavaScript 文件在此定義的組件都代表應用程序中的一個路由。
notion image
換句話說,這裡的文件結構與用戶將導航到的實際 URL 相對應,並且 Next.js 提供了自己的路由器,能使導航無縫切換。

✒️ 數據獲取

其實它真正的魔力在於數據獲取,因為 Next.js 可以從單個項目執行多個服務器渲染策略。
notion image
靜態生成(Static Generation)預渲染 讓您在構建時渲染頁面。每個頁面或組件可以實現一個名為 getStaticProps 的函數,它可以從雲數據庫獲取數據,然後將數據作為 props 傳遞給組件。
然後,您可以構建應用程序在本地呈現所有 HTML,並將其上傳到存儲槽(Storage Bucket),以便 CDN 輕鬆緩存。這對於博客或數據不經常更改的任何類型的應用程序非常適用。
但倘若數據經常更改,您可以實現 服務器端渲染(Server-side Rendering)。它都會在每次用戶請求時構建 HTML 頁面。在組件中,我們使用 getServerSideProps 函數來實現數據獲取,而不是在構建時運行。
也就是說,該函數在請求時運行,這意味著頁面將在每次新請求進來時從服務器獲取最新數據。對於數據快速變化的頁面非常適用。
但也許您想要介於兩者之間的某種選項,那麼另一個選擇是增量靜態再生(Incremental Static Regeneration)。通過簡單地向 getStaticProps 添加 revalidate 選項,Next.js 可以在一定時間間隔內每當有新請求時重新生成頁面。

✒️關於 Next.js 13

這是一個痛苦的故事。當初我剛開始用 Next.js 時,想說跟著別人的 project 教程做個簡單的 demo 熟悉一下,結果當時找到的全是 12 的。然後我就看著官方文檔慢慢摸,直到不久前才看到有人做 13 的教程,一開始看著那有點像又有點不像的目錄結構真的...唉...
Next.js 13 添加了一個新的 app 目錄,它仍然也像以前一樣使用基於文件系統的路由,只是現在它全部基於目錄結構,針對不同用例的一堆命名約定來創建頁面。要創建一個頁面,只需給目錄命名路由的名稱,然後在其中添加一個 page.js 文件,導出您想要顯示的組件,非常簡單。
notion image
然而,因為它是一個目錄,我們也可以在這裡放置額外的組件,而不需要創建單獨的組件目錄或其他類型的約定。
notion image
更重要的是,它為佈局和嵌套路由打開了大門。當您給文件命名為 layout.js 時,它將創建一個可以被子頁面重用的佈局組件。
notion image
這意味著您可以在應用程序中定義通用的佈局,並在多個頁面中重複使用它,這對於創建一致的用戶界面很有幫助。
notion image
此外,還可以在佈局中定義子路由,這為嵌套路由提供了簡單而直觀的方式。當你導航到佈局內部的路由時,它只渲染內部 UI,而不是渲染外部 UI。
還有用於 loading 和 error 的文件命名約定,可以根據其當前狀態在組件級別呈現不同的 UI。
notion image
例如,如果組件損壞,它將呈現 error.js 而不是 page.js ,而 UI 的其餘部分保持不變。
notion image
另一個令人興奮的功能是動態路由。在以前的版本中,您可能需要使用動態路由庫(如 react-router)來處理動態參數的路由,但在 Next.js 13 中,您可以直接在文件名中使用動態參數,例如[id].js。這使得處理動態路由變得非常簡單和直觀。
這個新版本中最史詩般的功能是 數據獲取(沒錯,又是它),默認情況下所有這些組件都是 React 服務器組件中的低級原語,可以啟用 服務器端渲染,但對於普通開發人員來說,使用它們總是有點困難。而現在我們可以完全擺脫諸如獲取 static props 和獲取 server-sid props 之類的東西,
notion image
而我們只需編寫一個使用 Fetch 的純 JavaScript 函數即可,然後直接在組件中等待該函數的結果,無需在客戶端和服務器之間來回傳遞 props,十分自然,就像您只是使用普通 JavaScript 一樣,甚至不需要序列化數據。
此外,您可以將之前提到 ISR、SSR 和 SSG 等概念,從您的大腦中 rm,新的思維模型完全圍繞 緩存(Caching)。默認情況下,所有頁面都將被緩存以維持靜態站點的性能。但如果您希望每個請求都有新數據像 SSR 一樣,您可以添加 cache: 'no-store' 選項來獲取,
或者對於增量靜態重新生成,添加 next: { revalidate: 420; }'
這一切的令人驚奇之處得於 React 暫停 UI 內容逐漸流入,你所要做的就是定義一個 loading.js 文件來定義 UI,如果組件仍在等待數據,它會自動在組件級別顯示它,在渲染其他應用程序內容時發揮作用,這是一個具有顛覆性的功能。
notion image
它其中許多功能顯然受到了 Remix 的啟發,但 Next 中免除了一種類似於 Remix 表單的數據編寫方式,我認為這是一個非常棒的功能。
notion image
但奇怪的是,新的應用程序目錄中沒有編寫 API 路由的方法。這是當初讓我非常痛苦的另外一點,當初我還問吳學長說怎麼 api folder 消失了。
正如我所展示的,數據獲取看起來很棒,但變更操作則完全不同。文檔中提到 Next 團隊正在為變更數據弄新的 RFC,但目前您將使用客戶端組件編寫變更邏輯,然後將刷新的回調函數傳遞給更新變更後該路由上的任何數據。這在某種程度上類似於 React Query 的工作方式,但似乎框架可以在這裡提供更直觀的解決方案。
總的來說,我認為Next 13看起來很棒,但這些重大變化,使得過往許多 Next.js 教程都過時了,即使這些變化是向前邁進的一步,但現實是人們往往不喜歡變化。就像 Vue2 轉向 Vue3 時,人們紛紛想舉牌上街抗議一樣,儘管它也可以逐步採用。現在每個人都對這些新功能感到非常興奮,但如果你是那個不得不遷移所有代碼的人,你最初的興奮可能很快會變成憤怒。
一則批評是,一個 Hello World 應用程序仍然是 90KB 的 JavaScript,
notion image
似乎它應該能夠發布 Zero JavaScript Apps,就像 Astro、Quick 一樣,但事實並非如此。
notion image
除了我提到的功能外,還有各種各樣的小優化,這邊就不細講了,因為我了解的不多。

Announcement
type
status
date
slug
summary
tags
category
icon
password
🎉新版博客即將到來🎉
-- 感谢您的注意 ---
👏為您帶來愉快的體驗👏