為什麼 TCA 要強迫你接受「單向資料流」?真正的問題從來不是架構,而是 State Chaos
很多 iOS 工程師第一次接觸 TCA(The Composable Architecture)時,第一反應通常是:
- 好複雜
- 好多 boilerplate
- 為什麼連按按鈕都要 dispatch action
- 為什麼不能直接改 state
- SwiftUI 不就已經有 @State 了嗎
但如果你真正做過大型 SwiftUI 專案,你很快就會發現:
TCA 真正想解決的,從來不是 UI 問題。
而是:
State Chaos(狀態失控)
1. 小型 SwiftUI 專案為什麼看起來很美好?
因為一開始:
@State private var count = 0
真的很舒服。
畫面:
Button {
count += 1
}
簡潔、直覺、快速。
但問題是:
真實產品不會只有一個 count
很快你會開始加入:
- loading state
- navigation state
- async state
- sheet state
- network state
- cache state
- login state
- pagination state
最後:
每個 View 都在持有自己的 state
2. 真正的問題:State 開始分散
這時候最可怕的事情開始發生:
- Child View 改 state
- Parent View 改 state
- ViewModel 改 state
- Service 改 state
- API callback 改 state
最後:
沒有人知道 state 到底是怎麼變的
這就是:
Shared Mutable State Chaos
也是大型 App 最痛苦的問題。
3. TCA 的第一個核心:Single Source of Truth
TCA 做的第一件事其實很簡單:
把 state 集中
例如:
struct AppState {
var count = 0
}
看起來沒什麼。
但這代表:
state 開始有唯一來源
這很重要。
因為大型系統最怕的是:
同一份資料存在多個版本
例如:
- View 一份 state
- ViewModel 一份 state
- Cache 一份 state
- Local copy 一份 state
最後:
資料不同步
4. Action 為什麼存在?
很多人最討厭:
store.send(.buttonTapped)
會覺得:
為什麼不能直接改 state?
因為:
直接修改 state 最大問題是:
你無法追蹤 state flow
TCA 強迫你:
所有 state change 都必須經過 action
這代表:
- state mutation 可追蹤
- 行為可記錄
- debug 可回放
- side effect 可觀察
這其實很像:
event sourcing thinking
5. Reducer 真正的目的不是「分層」
很多人以為 reducer 只是:
把 code 集中
其實不是。
Reducer 真正的價值是:
它讓 state mutation 變成 deterministic
例如:
Reduce { state, action in
switch action {
case .increment:
state.count += 1
return .none
}
}
現在:
input action → output state
變得:
- 可推理
- 可測試
- 可重現
這非常重要。
因為:
大型系統最怕「不可重現的 state」
6. 為什麼 TCA 幾乎禁止你自由改 state?
因為:
自由 mutation 幾乎一定會失控
這是大型架構最殘酷的現實。
一開始:
只是方便
後來:
變成沒人知道 state 從哪裡被改
TCA 的本質其實是:
限制 mutation 自由度,換取可預測性
7. Effect 為什麼要被隔離?
以前:
button tap
→ API request
→ callback
→ update UI
全部混在一起。
問題是:
side effect 開始污染 state flow
所以 TCA 強迫:
- state mutation 在 reducer
- async work 在 effect
- dependency 被注入
本質上是在做:
Side Effect Isolation
因為:
真正讓系統難維護的通常不是 UI
而是 side effect
8. 為什麼很多人覺得 TCA 很重?
因為:
TCA 強迫你面對系統複雜度
一般 SwiftUI:
viewModel.fetch()
很爽。
但:
很多複雜度其實只是被隱藏
例如:
- state flow 不明
- ownership 不明
- side effect 不明
- cancellation 不明
- dependency 不明
TCA 只是把這些:
全部顯性化
所以你才會覺得:
怎麼突然變這麼多 code
9. TCA 真正想解決的是「人類無法追蹤複雜度」
這才是最核心的地方。
當系統開始變大:
人腦無法同時追蹤所有 state change
所以:
- bug 開始不可預測
- state 開始互相污染
- side effect 開始亂飛
- async flow 開始失控
TCA 本質上是在做:
Complexity Compression
也就是:
把混亂 state flow 壓縮成可推理系統
10. TCA 為什麼跟 Swift 很契合?
因為 Swift 本身就在往同一方向前進。
例如:
- Value Type
- Immutable Thinking
- Actor Isolation
- Sendable
- Structured Concurrency
核心都在解決:
shared mutable state
而 TCA 只是把這個思想:
推到 App Architecture 層級
11. 面試真正想考的是什麼?
當面試問:
你為什麼用 TCA?
真正想知道的是:
- 你是否理解 state flow
- 你是否理解 predictable architecture
- 你是否理解 side effect isolation
- 你是否知道大型系統怎麼避免失控
真正成熟的工程師,不會只回答:
比較好測試
而是會知道:
TCA 本質上是在解決「大型 state system 的可預測性」
結論
TCA 從來不是:
比較潮的架構
它真正的核心其實是:
用限制換取可預測性
因為大型系統最危險的東西不是:
- UI
- API
- Thread
而是:
不可追蹤的 state mutation
延伸思考
當你開始深入:
- Reducer Architecture
- Elm Architecture
- Redux
- Actor Isolation
- Event Sourcing
你會發現:
現代前端與 App Architecture,其實都在往同一方向演化:
減少共享可變狀態。
因為:
State 一旦失控
系統就會開始失控。










