課程:Redux 思維與 RTK 核心 第 1 堂:Redux 思維建立
04從傳統 Redux 到 RTK
如果在一場開發者聚會中提到「Redux」,你很可能會聽到兩種截然不同的反應。資深開發者可能會感嘆它嚴謹的架構與強大的除錯能力,而新手或是曾被「傳統寫法」折磨過的開發者,則可能會露出痛苦的面孔,抱怨那寫不完的樣板程式碼(Boilerplate)。
為什麼一個標榜著「可預測性」與「嚴謹性」的工具,會讓這麼多開發者感到畏懼?
在我們學過了 Action、Reducer 與 Store 的資料流運作後,你可能會覺得:「邏輯聽起來很清晰,但如果要為了改一個數字而寫這麼多程式碼,是不是有點太累了?」你的直覺是對的。這正是為什麼 Redux Toolkit (RTK) 會誕生,並且成為今天官方唯一推薦的寫法。
這一部分,我們將深入探討傳統 Redux 的痛點,並揭開 RTK 是如何優雅地解決這些問題,同時又不破壞我們引以為傲的三大原則。
傳統 Redux 的三大難題
在 RTK 出現之前,寫 Redux 就像是在進行一場充滿儀式感的修行。為了實現一個最簡單的「加一」功能,你需要經歷一段漫長的開發流程。
1. 永無止境的樣板程式碼 (Boilerplate)
在傳統寫法中,要定義一個狀態更新,通常需要完成以下三個步驟:
- 定義 Action Type 字串:為了避免打錯字,我們會先定義一個常數,例如
const INCREMENT = 'counter/increment';。 - 撰寫 Action Creator 函式:我們需要一個函式來回傳 Action 物件,例如
const increment = () => ({ type: INCREMENT });。 - 在 Reducer 中撰寫 Switch-case:我們要在一個巨大的 Reducer 函式中,根據不同的
action.type來決定如何處理狀態。
這就是所謂的「樣板程式碼」。每增加一個小功能,你都要在多個檔案(或同檔案的多處)跳來跳去。這不僅增加了開發成本,更讓程式碼變得難以閱讀——邏輯被拆散在各地,你很難一眼看出「這個按鈕按下去,到底發生了什麼事」。
2. 手寫不可變更新 (Immutable Updates) 的痛苦
還記得 Redux 的第二大原則嗎?State 是唯讀的。我們不能直接修改 state,而必須回傳一個「全新的 state 物件」。
在傳統 Redux 中,我們重度依賴 JavaScript 的展開運算子 (...state)。如果你的狀態結構很簡單,那還好;但如果遇到巢狀物件(Nested Objects),程式碼就會變成一場災難:
// 傳統 Redux 的巢狀更新範例
case UPDATE_USER_CITY:
return {
...state,
user: {
...state.user,
address: {
...state.user.address,
city: action.payload
}
}
};
這種寫法極度容易出錯。只要漏掉一個 ...,你的部分狀態就會在這次更新中「神隱」。這種「手動維護不可變性」的過程,是許多 React 開發者對 Redux 望而卻步的主因。
3. 設定過程極其繁瑣
如果你想在傳統 Redux 專案中啟用 Redux DevTools 或處理非同步邏輯(如 redux-thunk),你必須在建立 Store 時進行繁雜的配置:
- 手動調用
combineReducers。 - 手動串接
applyMiddleware。 - 手動檢查環境變數以決定是否開啟開發者工具。
對於想快速啟動專案的開發者來說,這些「基礎建設」的成本高得嚇人。
Redux Toolkit:現代開發的救星
Redux 官方意識到了這些痛點。他們並不想改變 Redux 的核心哲學,而是想改變開發者的「寫作體驗」。於是,Redux Toolkit (RTK) 應運而生。
RTK 並不是一個與 Redux 競爭的新框架,它是 Redux 的「標準封裝」。它就像是為你的手動排檔車換上了頂級的自排系統,核心引擎沒變,但開起來順暢多了。
核心 API 1:createSlice —— 讓 Action 與 Reducer 合而為一
這是 RTK 最具革命性的改進。createSlice 允許你將「初始狀態」、「Reducer 邏輯」與「Action」寫在同一個物件裡。
想像一下:以前你要分別定義 Action Type、Action Creator 和 Reducer,現在你只需要定義一個名稱叫做 counter 的 Slice,RTK 就會自動幫你生成對應的 Action Types(例如 counter/increment)和 Action Creators。
你不再需要手寫 switch-case,也不再需要擔心字串打錯的問題。所有的邏輯都被高度封裝在「切片 (Slice)」的概念中。
核心 API 2:內建 Immer —— 魔法般的「可變」語法
還記得剛才那個讓人頭痛的展開運算子嗎?在 RTK 的 createSlice 內部,它整合了一個強大的函式庫叫做 Immer。
Immer 的運作機制非常巧妙:它會提供一個狀態的「草稿 (Draft)」。你可以在這個草稿上直接進行修改,就像你平時修改普通 JavaScript 物件一樣。
- 預測:如果你寫下
state.user.value += 1,Redux 的狀態會被破壞嗎? - 揭曉:不會。因為 Immer 會在背後監控這些修改,並根據你的修改自動生成一個全新的、不可變的 State。
這意味著你可以寫出最直覺的程式碼,同時仍然嚴格遵守 Redux 的「不可變更新」原則。這不僅減少了代碼量,更徹底消滅了因為漏寫展開運算子而產生的 Bug。
核心 API 3:configureStore —— 聰明的預設設定
傳統的 createStore 就像是給你好幾個零件讓你組裝;而 configureStore 則像是提供了一個已經配備完善的豪華座駕。
當你使用 configureStore 時:
- 它會自動幫你組合多個 Reducers。
- 它預設就開啟了 Redux DevTools,你不需要寫任何額外的配置。
- 它自動加入了
redux-thunk(用於非同步)以及開發環境下的「狀態修改偵測(Serializability check)」等 Middleware。
你只需要專注於定義你的業務邏輯,基礎建設的事情,交給 RTK 就好。
RTK 的本質:它仍然是 Redux
在學習 RTK 的過程中,新手最容易產生的誤解是:「我是在學一個叫 RTK 的新東西,而不是在學 Redux。」
請記住:RTK 就是 Redux。
它完全遵循我們在上一章節學到的 資料單向流動 (Unidirectional Data Flow):
- 你依然需要透過 Dispatch 發送一個 Action。
- Reducer 依然是一個純函式(雖然有了 Immer 讓它看起來像在修改狀態,但本質上它仍然回傳新物件)。
- Store 依然是唯一的實體。
RTK 的出現並不是要推翻 Redux 的三大原則,相反地,它是為了更好地實踐這三大原則。透過自動化生成的 Action 與內建的不可變性處理,RTK 讓「做正確的事(遵守原則)」變得比「做錯誤的事(直接修改狀態)」更容易。
這就是所謂的 「有意見的 (Opinionated)」框架設計。它幫你選好了最佳實踐,讓你少走彎路。
為什麼這對你的鐵人賽文章至關重要?
當你在撰寫關於 Redux 的教學文章時,區分「傳統寫法」與「現代 RTK 寫法」是非常關鍵的。這不僅展現了你的知識深度,更能幫助讀者理解技術演進的脈絡。
如果你直接教 RTK 而不解釋它解決了什麼問題,讀者可能會覺得 createSlice 的語法很神奇,但不知道為什麼要這麼麻煩地定義 Slice。反之,如果你先點出傳統寫法的痛苦(樣板程式碼、展開運算子的風險),讀者在看到 RTK 的簡潔語法時,就會產生那種「Aha! Moment」——這就是他們會持續追蹤你文章的原因。
本課程的實作策略
在接下來的課程中,我們將全方位採用 RTK + TypeScript 的組合。
- 我們會利用
createSlice的型別推導能力,確保開發過程中的型別安全。 - 我們會透過
configureStore建立起一個結構清晰的 Store 專案架構。 - 我們將不再手寫任何一個傳統的 Action Type 常數。
這套寫法不僅是官方推薦,更是目前業界在處理大型專案時的標準配置。
建立正確的技術心智模型
總結這堂課我們所建立的 Redux 世界觀:
- 為什麼需要狀態管理? 因為 Props Drilling 會讓開發變成地獄,而 Context API 在效能與除錯上有其侷限。
- Redux 的靈魂是什麼? 是「三大原則」。單一來源、狀態唯讀、純函式更新,這三者共同創造了「可預測性」。
- 資料怎麼動? 永遠是單向的。從 View 觸發 Action,交給 Reducer 運算,最後更新 Store 並回傳給 View。
- 為什麼要用 RTK? 因為傳統 Redux 寫起來太痛苦。RTK 透過
createSlice和 Immer 等工具,讓我們能用最少的程式碼,寫出最符合原則的邏輯。
掌握了這些思維邏輯後,你已經跨過了 Redux 最難的一道關卡——「理解為什麼」。剩下的 API 用法與語法細節,都只是為了實踐這些想法的工具而已。
邁向實作的第一步
我們已經完成了完整的思維建模。現在,你的腦中已經有了一張清楚的地圖,知道我們從哪裡來(Props Drilling 的痛),也知道我們要往哪裡去(簡潔的 RTK 實作)。
下一堂課,我們將離開理論的舒適區,進入真正的程式碼世界。我們將從環境建置開始,手把手帶你使用 Vite 建立一個現代化的 React + TypeScript 專案,並安裝所有必要的 Redux 齒輪。準備好你的終端機,我們要開始動手建構你的第一個專業級狀態管理系統了。給予
掌握現代 Redux 的核心權威
這堂課我們從傳統 Redux 的冗餘痛點出發,對比了 Redux Toolkit 如何透過 createSlice、configureStore 與 Immer 簡化開發流程。你已經理解 RTK 並非改變了 Redux 的本質,而是透過封裝最佳實踐,讓開發者能以更直覺、更安全的方式遵循 Redux 的核心原則。這套思維將支撐你撰寫出具備深度與說服力的教學文章。
接下來,我們將進入實作階段,動手建置開發環境。你將學習如何利用 Vite 快速啟動專案,並完成 RTK 與 TypeScript 的初始設定,為後續的 Slice 設計打下穩固的基礎。