React 的狀態類型
-
Client State:用戶端的狀態,包含各種和使用者狀態或互動相關的資料。
-
Server State:來自伺服器或 API 的資料,通常是後端服務或第三方 API 提供的數據。管理伺服器狀態涉及資料的請求、緩存、同步處理、以及錯誤處理。
以下討論的內容都集中在 Client State 上,Server State 的部份會在之後的文章說明。
你其實不一定需要用到狀態管理套件
React 提供了許多內建的工具來管理狀態,在一般情況下已經足夠:
-
useState : 最基本的狀態管理 hook,用來管理簡單的狀態,透過 setState 來觸發資料更新。
-
useReducer : 適合處理比較複雜的狀態邏輯,特別是當有多個 action 影響同一個狀態時。
傳遞資料的方式:
-
將 JSX 當作 children: 在某些情況下,可以不需要使用 props,而是將 JSX 元素直接作為 children 來傳遞。例如,將
<Layout posts={posts} />
改為 <Layout><Posts posts={posts} /></Layout>
,這樣 Posts 就成為 Layout 的一部分,減少了傳遞層級。
-
props: 父元件透過 props 將資料傳遞給子元件。需要注意的是,當 props 改變時,除非使用 React.memo 或 useMemo,否則不會自動觸發子元件的重新渲染。
-
Context: Context 讓資料可以直接傳遞給樹狀結構中的任何子元件,而不需要透過層層的 props 傳遞,通常用於不常改變的資料,像是外觀主題或用戶資訊。
在 React 19,可以用 <Context>
取代 <Context.Provider>
const ThemeContext = createContext("");
function App({ children }) {
return <ThemeContext value="dark">{children}</ThemeContext>;
}
子元件要使用的話如下
const theme = useContext(ThemeContext);
除此之外,有時也可以將狀態存在 URL 中,這樣當用戶分享該 URL 時,應用的狀態也會保存並重現。
為什麼需要用到 React 狀態管理套件?
當應用規模變大、邏輯變得更複雜時,可能會面臨以下問題可:
-
Props Drilling:因為 React 是單向資料流,當需要將資料傳遞給深層的子元件時,必須透過多層的 props 傳遞。
-
大量的 Context:當應用中的狀態管理變得複雜時,使用多個 Context 會讓程式碼變得難以維護。
-
重複渲染 : 雖然 Context 解決了 props drilling,的問題,但會有潛在的效能問題。當 Context 的值改變時,所有使用該 Context 的元件都會重新渲染,即使某些元件並不需要更新的資料。為了避免這種情況,需要使用 useMemo 和 useCallback 來進行優化,增加程式碼的複雜性。
目前比較熱門的兩個狀態管理套件是 Redux Toolkit 和 Zustand,它們都是基於 Flux 架構。除此之外,還有其他的狀態管理解決方案,如 MobX、Jotai、Recoil 等,可以根據自身需求選擇合適的工具。
Flux 架構
Flux 是由 Facebook 提出的一種單向數據流的架構模式。
Flux 的組成部份
-
Action : 用來描述應用中發生的事件,Action 並不會直接改變應用的狀態,而是被傳送給 Dispatcher。
-
Dispatcher : Dispatcher 負責傳遞 Action。它會把剛剛產生的 Action 傳送給應用裡負責處理資料的部分。應用裡通常只有一個 Dispatcher,負責處理所有的 Action。
-
Store : Store 是儲存應用裡所有資料的地方。當 Store 收到 Dispatcher 傳來的 Action 之後,會根據 Action 的內容來更新裡面的資料。Store 更新完資料後,會告訴畫面要重新顯示最新的資料。
-
View : View 就是使用者看到的畫面,一般是由 React 組件組成的。當 Store 的資料有更新時,View 就會重新顯示,讓使用者看到最新的內容。當使用者在 View 上進行操作時,會產生 Action,然後進一步驅動應用的資料更新。
Flux 流程
- 使用者在 View 操作產生一個 Action。
- Dispatcher 接收 Action,然後把它發送給 Store。
- Store 根據 Action 來更新裡面的資料,然後通知 View。
- View 收到通知後,會重新顯示更新過的資料。
在圖中也有一個 Action 不是來自 View,這是因為有些 Action 是由應用程式內部邏輯或是外部系統觸發的。
下一篇文章將詳細探討 Redux Toolkit 和 Zustand 的具體運作方式。
參考資料和圖片來源:
https://www.youtube.com/watch?v=5-1LM2NySR0
https://react.dev/blog/2024/04/25/react-19
https://react.dev/learn/managing-state
https://github.com/facebookarchive/flux
https://github.com/facebookarchive/flux/tree/main/examples/flux-concepts