React 19 全面指南與功能開箱 探索 Server Component 與 Actions 於非同步處理之優化

me
林彥成
2024-12-14 | 8 min.
文章目錄
  1. 1. 什麼是 React 19?
  2. 2. React 19 Server Component:前端與後端的無縫整合
  3. 3. React 19 Actions:簡化非同步操作與表單處理
    1. 3.1. useActionState:非同步狀態管理
    2. 3.2. useOptimistic:提升用戶體驗
    3. 3.3. use API:輕鬆讀取資源
  4. 4. 簡化 Ref 使用:React 19 的新特性
  5. 5. useDeferredValue:React 19 延遲更新的效能優化利器
  6. 6. React 19 樣式與資源載入效能提升:加速網頁響應
  7. 7. 內建支援 Meta Data:React 19 的 SEO 強化功能
  8. 8. 優化樣式表載入:React 19 提升視覺呈現速度
  9. 9. 支援非同步腳本:React 19 的高效資源管理
  10. 10. 資源預載入支援:React 19 加速首次內容繪製
  11. 11. React 19 完整支援 Web Component:提升相容性與靈活性
  12. 12. FAQ:React 19 常見問題快速解答
    1. 12.1. Q1:升級 React 19 會導致現有程式碼壞掉嗎?
    2. 12.2. Q2:什麼時候該使用 Server Components?
    3. 12.3. Q3:React 19 的 Actions 可以取代 React Query 嗎?
  13. 13. React 19 華麗登場:開發者不可錯過的全面升級與展望

什麼是 React 19?

React 19 是 React 框架的一個重大版本更新,核心聚焦於簡化非同步資料處理、提升伺服器端整合與優化開發者體驗。最受矚目的新功能包括正式穩定版的 Server Components、簡化表單提交的 Actions,以及多個全新 Hooks(如 useActionStateuseOptimisticuse API)。此外,React 19 也大幅優化了樣式表、資源預載入與 Web Components 的支援,讓前端開發更直覺且效能更卓越。


餓死抬頭,React 19 究竟是繼 v18 睽違兩年華麗登場?! 還是十年走來始終如一?! 相對於 Angular 每次升級每次 Breaking Change,這次的 React 19 更新看起來不僅不想拖過年,也把 Nextjs Canary 許久的 Server Component 穩定版進行釋出。這次的更新,可謂是 React 開發者體驗 的一次革命性提升。

一如既往的可以無痛升級,這次升級雖然也有一些必要改變,但也提早在 v18 的小版本釋出中提出警告,基於 v18 穩定和表現基礎上實現了多項重大功能提升和優化。接近兩年的蟄伏究竟帶來了什麼改變?! 這份 React 19 全面解析 將帶您一探究竟。

React 19 不僅僅是版本更新,而是對開發者體驗和應用性能的全方位升級。React 19 引入了全新的 API 和 Hooks,改善了 React 內部多個機制,讓開發者能夠更高效地構建現代 Web 應用。

接下來一起來從實際開發者體驗的角度,介紹 React 19 中幾個關鍵新特性,並解釋它們如何簡化開發流程和提升應用效能。

React 19 Server Component:前端與後端的無縫整合

目前看起來雖然穩定,但絕大多數工具跟框架都尚未完全整合和支援。React 19 Server Component 可以看作是為未來的開發模式提前準備,它模糊了前端與後端的界限,帶來了以下幾個重要變革:

  • Actions:提供了 Client 跟 Server 都支援的寫法,極大簡化了資料提交與狀態更新。
  • 內建支援使用 Meta Data:讓 SEO 優化變得更加便捷高效。
  • 完整支援 web component:提升了與原生 Web 技術的相容性。

React 19 Actions:簡化非同步操作與表單處理

React 19 介紹了 Actions 的概念,這是一種更強大、更統一的非同步操作處理方式,它取代了傳統的事件處理器,並與 React 的 transitions 和 concurrent features 深度整合。

Actions 可以在客戶端和伺服器端使用,例如可以使用 Client Action 來替代之前的 onSubmit 事件處理器來處理表單,使用 Action 時不需要解析事件,Action 會直接接收 FormData。

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
import { useState } from "react";

export default function TodoApp() {
const [items, setItems] = useState([{ text: "我的第一個待辦事項" }]);

async function formAction(formData) {
const newItem = formData.get("item");
// 可以向伺服器發送 POST 請求來儲存新項目
setItems((items) => [...items, { text: newItem }]);
}

return (
<>
<h1>待辦清單</h1>
<form action={formAction}>
<input type="text" name="item" placeholder="新增待辦..." />
<button type="submit">新增</button>
</form>
<ul>
{items.map((item, index) => (
<li key={index}>{item.text}</li>
))}
</ul>
</>
);
}

useActionState:非同步狀態管理

React 19 中加入了 useActionState Hook 簡化程式碼,專門用來簡化非同步資料處理和狀態管理,開發者不再需要手動追蹤請求狀態、錯誤信息或更新順序,Actions 提供自動管理的待處理狀態,當請求開始時 isPending 會設置為 true,並在最終更新後自動重置。

例如當用戶提交表單時,React 19 可以自動管理 API 請求的等待狀態和錯誤處理,這使得開發者能更專注於業務邏輯,而不必關心繁瑣的狀態管理細節。

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
27
// 使用 Actions 的待處理狀態
function UpdateName({}) {
const [name, setName] = useState("");
const [error, setError] = useState(null);
const [isPending, startTransition] = useTransition();

const handleSubmit = () => {
startTransition(async () => {
const error = await updateName(name);
if (error) {
setError(error);
return;
}
redirect("/path");
});
};

return (
<div>
<input value={name} onChange={(event) => setName(event.target.value)} />
<button onClick={handleSubmit} disabled={isPending}>
更新
</button>
{error && <p>{error}</p>}
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 使用 <form> Actions 和 useActionState
function ChangeName({ name, setName }) {
const [error, submitAction, isPending] = useActionState(
async (previousState, formData) => {
const error = await updateName(formData.get("name"));
if (error) {
return error;
}
redirect("/path");
return null;
},
null
);

return (
<form action={submitAction}>
<input type="text" name="name" />
<button type="submit" disabled={isPending}>
更新
</button>
{error && <p>{error}</p>}
</form>
);
}

useOptimistic:提升用戶體驗

React 19 引入了 useOptimistic Hook,通過實現樂觀更新來提升應用的響應速度。用戶送出請求後,應用會立刻顯示預期結果,並在後端回應後進行最終更新而減少等待時間。

  • 如果成功,會直接用新的 state 覆蓋預期結果
  • 如果失敗,會直接取消 UI 的更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function ChangeName({ currentName, onUpdateName }) {
const [optimisticName, setOptimisticName] = useOptimistic(currentName);

const submitAction = async (formData) => {
const newName = formData.get("name");
setOptimisticName(newName);
const updatedName = await updateName(newName);
onUpdateName(updatedName);
};

return (
<form action={submitAction}>
<p>Your name is: {optimisticName}</p>
<p>
<label>Change Name:</label>
<input
type="text"
name="name"
disabled={currentName !== optimisticName}
/>
</p>
</form>
);
}

use API:輕鬆讀取資源

React 19 引入的 use API 讓開發者能夠在渲染過程中直接讀取非同步資源(如 Promise 或 Context),並且由 React 自動處理懸掛(suspense)機制,直到資源準備好為止,這樣就可以簡化資料的處理流程,不必手動管理載入狀態。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { use } from "react";

function Comments({ commentsPromise }) {
// `use` 會在 promise 解決之前進行 suspend
const comments = use(commentsPromise);
return comments.map((comment) => <p key={comment.id}>{comment}</p>);
}

function Page({ commentsPromise }) {
// 當 `use` 在 Comments 中 suspend 時,
// 這個 Suspense 邊界會顯示
return (
<Suspense fallback={<div>Loading...</div>}>
<Comments commentsPromise={commentsPromise} />
</Suspense>
);
}

簡化 Ref 使用:React 19 的新特性

React 19 改善了對 Ref 的使用,支援將 Ref 作為 props 傳遞給函式元件,並增加了對 Ref 清理函式的支援。這使得管理元件的 Ref 更加簡單且直觀,不再需要使用 forwardRef,進一步提升了開發者體驗。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function MyInput({ placeholder, ref }) {
return (
<input
placeholder={placeholder}
ref={(ref) => {
// ref 被創建

// 新增:返回一個清理函式,當元素從 DOM 中移除時重置 ref
return () => {
// ref 清理邏輯
};
}}
/>
);
}

// 使用時:
<MyInput ref={ref} />;

useDeferredValue:React 19 延遲更新的效能優化利器

React 19 引入了 useDeferredValue Hook,它允許在初始渲染時使用預設值,並將數據更新推遲至背景中進行,這樣就能有效減少數據變更對渲染性能的影響,對於提升用戶體驗尤為重要。

1
2
3
4
5
6
7
function Search({ deferredValue }) {
// 初次渲染時,value 是空字串 ('')。
// 隨後會安排在背景中使用 deferredValue 重新渲染。
const value = useDeferredValue(deferredValue, "");

return <Results query={value} />;
}

React 19 樣式與資源載入效能提升:加速網頁響應

React 19 針對樣式表和資源載入進行了深度優化,支援在客戶端渲染和伺服器端渲染中更好地整合和載入資源,從而顯著提升了應用的載入速度和流暢度。

開發者可以更加靈活地控制樣式表的載入順序,保證依賴樣式表的內容在樣式表載入後才會渲染,避免因樣式表未載入完全而導致的渲染問題。

內建支援 Meta Data:React 19 的 SEO 強化功能

React 19 中,對 Meta Data 提供了原生支援,實現了在元件中渲染文檔標籤(如 <title><link><meta>),並將它們自動提升到文檔的 <head> 區域。

這確保了這些元資料標籤在客戶端應用、流式 SSR 和伺服器端元件中的正常運作,從而提升了性能,雖然 React 提供了內建支援,對於更複雜的場景,您仍然可以選擇使用第三方庫來處理元資料,例如 react-helmet,它可以根據當前路由動態更新元資料。

1
2
3
4
5
6
7
8
9
10
11
12
function BlogPost({ post }) {
return (
<article>
<h1>{post.title}</h1>
<title>{post.title}</title>
<meta name="author" content="Josh" />
<link rel="author" href="https://twitter.com/joshcstory/" />
<meta name="keywords" content={post.keywords} />
<p>Eee equals em-see-squared...</p>
</article>
);
}

優化樣式表載入:React 19 提升視覺呈現速度

React 19 引入了樣式表的內建支援,進一步提升了客戶端和伺服器端渲染的性能,尤其是在提升視覺呈現速度方面。

在渲染包含樣式表的元件時,React 會根據設置的優先順序自動管理樣式表在 DOM 中的插入順序,確保樣式表先於內容渲染。

  • 伺服器端渲染:React 會確保樣式表在流式渲染過程中提前載入,避免阻塞頁面渲染。
  • 客戶端渲染:React 確保樣式表載入完成後再進行渲染,並且多次渲染同一元件時,樣式表只會被載入一次。
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
27
28
29
30
31
function ComponentOne() {
return (
<Suspense fallback="loading...">
<link rel="stylesheet" href="foo" precedence="default" />
<link rel="stylesheet" href="bar" precedence="high" />
<article className="foo-class bar-class">
{...}
</article>
</Suspense>
);
}

function ComponentTwo() {
return (
<div>
<p>{...}</p>
<link rel="stylesheet" href="baz" precedence="default" /> {/* 將會被插入在 foo 和 bar 之間 */}
</div>
);
}

function App() {
return (
<>
<ComponentOne />
...
<ComponentOne /> {/* 不會在 DOM 中導致樣式表鏈接重複 */}
</>
);
}

支援非同步腳本:React 19 的高效資源管理

React 19 在非同步腳本的載入管理上提供了更高效的支援。無論腳本位於元件樹的何處,React 19 都能確保非同步腳本只會載入一次,從而提升性能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function MyComponent() {
return (
<div>
<script async={true} src="..." />
Hello World
</div>
);
}

function App() {
return (
<html>
<body>
<MyComponent />
...
<MyComponent /> {/* 不會導致 DOM 中的腳本重複 */}
</body>
</html>
);
}

資源預載入支援:React 19 加速首次內容繪製

React 19 引入了資源預載入 API,可以讓瀏覽器更早地載入必要的資源,顯著提高頁面性能。這些 API 能夠幫助優化頁面載入速度,並讓資源更快地準備好以應對用戶交互,特別是在加速首次內容繪製 (First Contentful Paint) 方面。

  • 預載入字體、樣式表等資源:可以在頁面載入之前提前載入字體和樣式表,從而減少頁面顯示的延遲。
  • 預先載入導航所需資源:當用戶進行點擊或懸停操作時,預載入未來導航可能需要的資源,加速頁面更新。
1
2
3
4
5
6
7
8
9
import { prefetchDNS, preconnect, preload, preinit } from "react-dom";

function MyComponent() {
preinit("https://.../path/to/some/script.js", { as: "script" }); // 預先載入並執行此腳本
preload("https://.../path/to/font.woff", { as: "font" }); // 預載入此字體
preload("https://.../path/to/stylesheet.css", { as: "style" }); // 預載入此樣式表
prefetchDNS("https://..."); // 當你可能不會從此主機請求任何內容時使用
preconnect("https://..."); // 當你將會請求某些東西,但不確定具體請求的資源時使用
}
1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head>
<!-- 根據資源對早期載入的實用性優先排序,而非調用順序 -->
<link rel="prefetch-dns" href="https://..." />
<link rel="preconnect" href="https://..." />
<link rel="preload" as="font" href="https://.../path/to/font.woff" />
<link rel="preload" as="style" href="https://.../path/to/stylesheet.css" />
<script async="" src="https://.../path/to/some/script.js"></script>
</head>
<body>
...
</body>
</html>

React 19 完整支援 Web Component:提升相容性與靈活性

React 19 完全支援 Web Components,並解決了以前版本中使用 Web Components 的一些相容性問題。現在,React 能夠正確處理傳遞給自訂元素的屬性,無論是在伺服器端渲染還是客戶端渲染中,都能夠精確區分和處理屬性與自訂元素的實際屬性,這使得 React 更加靈活和強大。

  • 伺服器端渲染(SSR):當傳遞給自訂元素的 props 是基礎類型(例如字串、數字或值為 true)時,會作為屬性渲染。如果 props 是非基礎類型(例如物件、符號、函式或值為 false),則會被省略。
  • 客戶端渲染(CSR):當 props 與自訂元素實例的屬性相符時,將被作為屬性分配給該元素,否則會作為屬性分配。這樣的設計讓 React 更加靈活地支援自訂元素,解決了先前的相容性問題,無論是在伺服器端還是客戶端渲染中,處理方式都能有效區分屬性和自訂元素的實際屬性。

https://custom-elements-everywhere.com/

FAQ:React 19 常見問題快速解答

Q1:升級 React 19 會導致現有程式碼壞掉嗎?

A:大多數應用可以平滑升級。主要變更包括移除了 forwardRef(現在可以直接在 Props 中接收 ref)以及對 ref 清理函數的支援。建議先升級到 v18.3 並解決所有 Console 警告。

Q2:什麼時候該使用 Server Components?

A:當元件主要負責資料抓取且不需要互動(如讀取資料庫列表)時,使用 Server Components 能顯著減少傳送到客戶端的 JS 體積。若需要使用 useState 或事件監聽,則應使用 Client Components(加上 'use client' 指令)。

Q3:React 19 的 Actions 可以取代 React Query 嗎?

A:Actions 主要處理「資料突變」(Mutations/Post)與表單提交。對於複雜的資料快取與同步(Query/Fetch),React Query 或 SWR 仍然是非常強大的互補工具。

React 19 華麗登場:開發者不可錯過的全面升級與展望

React 19 引入的這些新特性不僅提升了開發者的工作效率,還大幅改善了應用的性能和用戶體驗。

從簡化非同步狀態管理的 useActionState 到提升響應速度的 useOptimistic,再到優化資源載入和對 Web Components 的支援,顯著提高了頁面的載入性能和流暢度。無論是伺服器端渲染還是客戶端渲染,這些改進都能幫助開發者構建更加高效的應用。

如果你是一名 React 開發者,這些新特性無疑會讓你的開發過程更加順利,並能構建出更高效、流暢的應用。


喜歡這篇文章,請幫忙拍拍手喔 🤣