这是一个所有“状态驱动 UI”体系的核心问题。
如果把它搞清楚,SwiftUI / TCA / Redux / Jetpack Compose 的 80% 性能与一致性问题都会自动消失。
- 什么是 State vs Derived State(工程定义)
- 最小判定法则(实用)
- 错误区分会导致的“一致性灾难”
- 错误区分导致的“性能陷阱”
- SwiftUI / TCA 中的落地策略
一、先给一句工程级定义(不是教科书)
✅ State(源状态)
State = 系统必须“记住”的最小事实集合
- 不可从其他状态推导
- 丢失就无法恢复
- 生命周期明确
✅ Derived State(派生状态)
Derived State = 从 State 计算得出的视图或业务投影
- 可 100% 从 State 重新算出
- 不需要被“记住”
- 只为方便使用 / 性能
State ──计算──▶ Derived State
二、一个“不会错”的判定法则(强烈建议背下来)
如果删掉这个字段,只靠其他 State 能 100% 还原它,它就不是 State。
三、经典错误一:把 Derived State 当成 State(最常见)
❌ 错误示例
struct State {
var items: [Item]
var totalPrice: Double // ❌ Derived
}
totalPrice 明明可以:
items.reduce(0) { $0 + $1.price }
一致性灾难如何发生?
Action A → 改 items
❌ 忘了改 totalPrice
或者:
Action B → 改 totalPrice
❌ items 没变
结果:
- UI 显示错
- Bug 偶现
- Debug 极难
👉 双源真相(Two Sources of Truth)
四、经典错误二:把 State 当 Derived State(隐蔽但致命)
❌ 错误示例
var filteredUsers: [User] {
users.filter { $0.name.contains(searchText) }
}
然后在 body 里:
List(filteredUsers) { ... }
看似没问题,但:
- filter 很重
- 每次 diff 都会算
- 输入就卡
五、错误区分导致的两类灾难
🧨 灾难一:一致性问题(逻辑层)
症状
- 同一数据在不同页面值不同
- UI 偶尔“自己修复”
- 重进页面就好了
根因
Derived State 被持久化,且更新路径不唯一
🧨 灾难二:性能问题(渲染层)
症状
- SwiftUI 输入卡顿
- List 滚动掉帧
- CPU 异常
根因
Derived State 在 body / 高频路径中重复计算
六、那 Derived State 到底应该放哪?
答案不是“不要”,而是:
放在“离使用者最近,但不参与一致性”的地方
策略一:即时计算(轻量)
var isValid: Bool {
email.contains("@")
}
- 计算便宜
- 不存
策略二:缓存为局部 State(性能优化)
@State private var filtered: [User] = []
.onChange(of: searchText) {
filtered = users.filter(...)
}
👉 Derived State,但显式缓存
策略三:ViewModel / Adapter 层
final class ViewModel {
let users: [User]
var filteredUsers: [User] { ... }
}
- SwiftUI body 干净
- 性能可控
策略四:TCA 中的 computed / Selector
var totalPrice: Double {
state.items.reduce(...)
}
或 memoized selector。
七、SwiftUI 里的黄金规则(非常重要)
@State只能用于“用户直接操纵的最小事实”
不是:
- 显示文本
- 排序结果
- 是否可点击(通常 derived)
而是:
- 输入值
- 选择项
- 展开 / 折叠
- 当前焦点
八、一个真实“修复即提速”的案例
❌ 改前
@State var sortedItems: [Item]
- 每次数据源变化都要同步
- 状态错乱
✅ 改后
var sortedItems: [Item] {
items.sorted(by: ...)
}
或缓存到 ViewModel。
👉 一致性消失 + diff 成本下降。
九、终极心法(适用于任何架构)
State 越少,系统越稳定;
Derived State 越靠近消费端,系统越快。
最后一句话(架构级)
State 是“必须记住的事实”,
Derived State 是“可以随时算出的观点”。
混淆它们,系统就会同时变慢、变乱、变不可维护。