Store 与 SwiftUI 集成
通过 TCA store 驱动视图。
Store 与 SwiftUI 集成 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
什么是 Store
Store 是一个运行时对象,用于保存功能状态并运行其归约器。SwiftUI 视图会观察 Store 以读取状态,并向它发送操作来触发变化。
Store 是纯归约器逻辑与实时交互界面之间的桥梁。
import ComposableArchitecture
import SwiftUI
// A Store holds State, runs the Reducer,
// and is observed by SwiftUI views.StoreOf 类型别名
StoreOf<Feature> 是一个便捷别名,表示针对某个功能的状态类型和操作类型进行专门化的 Store。视图通常会将它作为存储属性。
因此,计数器视图会存储一个 StoreOf<CounterFeature>。
import ComposableArchitecture
import SwiftUI
struct CounterView: View {
let store: StoreOf<CounterFeature>
var body: some View {
Text("Count: \(store.count)")
}
}创建 Store
您可以使用 Store 初始化器创建 Store,并提供初始状态以及要运行的归约器。通常,您会在应用入口附近只执行一次此操作。
尾随闭包会返回功能的一个实例。
import ComposableArchitecture
import SwiftUI
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
CounterView(
store: Store(initialState: CounterFeature.State()) {
CounterFeature()
}
)
}
}
}直接读取状态
借助现代观察机制,视图可以使用点语法直接从 Store 读取状态,例如 store.count。由于状态是 @ObservableState,SwiftUI 只会重新渲染依赖于已变化值的部分。
对于简单读取,不需要额外的包装器。
import ComposableArchitecture
import SwiftUI
struct CounterView: View {
let store: StoreOf<CounterFeature>
var body: some View {
VStack {
Text("Count: \(store.count)")
}
}
}发送操作
要改变状态,视图可以通过 store.send(.someAction) 发送操作。Store 会将操作传递给归约器,由归约器修改状态,并可能启动效果。
这里的按钮会发送递增和递减操作。
import ComposableArchitecture
import SwiftUI
struct CounterView: View {
let store: StoreOf<CounterFeature>
var body: some View {
HStack {
Button("-") { store.send(.decrementTapped) }
Text("\(store.count)")
Button("+") { store.send(.incrementTapped) }
}
}
}从 Store 创建绑定
对于需要双向绑定的 SwiftUI 控件,TCA 允许您在状态使用可绑定操作时,从 Store 派生出一个 Binding。控件通过发送绑定操作来更新状态。
这里的 TextField 绑定到一个名称字段。
import ComposableArchitecture
import SwiftUI
struct FormView: View {
@Bindable var store: StoreOf<FormFeature>
var body: some View {
TextField("Name", text: $store.name)
}
}旧式 WithViewStore
在观察机制出现之前,视图会使用 WithViewStore 包装界面,以读取状态并获取用于发送操作的 viewStore。您仍会在较旧的代码中看到这种写法。
observe 闭包会选择视图所依赖的状态。
import ComposableArchitecture
import SwiftUI
struct LegacyCounter: View {
let store: StoreOf<CounterFeature>
var body: some View {
WithViewStore(store, observe: { $0 }) { viewStore in
Text("Count: \(viewStore.count)")
}
}
}选择要观察的内容
在旧式写法中,observe 闭包会缩小视图所观察的状态范围,因此只有这些值发生变化时,视图才会重新渲染。观察整个状态最简单;观察状态子集则可以优化大型视图。
现代的 @ObservableState 会自动处理这些工作,但理解 observe 有助于您阅读旧代码。
import ComposableArchitecture
import SwiftUI
// Observe just the count to limit re-renders:
WithViewStore(store, observe: { $0.count }) { viewStore in
Text("\(viewStore)")
}发送带载荷的操作
发送带有关联值的操作时,需要提供该值。这是视图转发归约器所需用户输入的方式。
这里,选择一行会发送所选行的标识符。
import ComposableArchitecture
import SwiftUI
struct ListView: View {
let store: StoreOf<ListFeature>
var body: some View {
Button("Pick 42") {
store.send(.rowSelected(id: 42))
}
}
}为操作添加动画
您可以为发送的操作附加动画,使由此产生的状态变化带有动画效果。请将 animation 参数传递给 send。
这样可以将动画相关逻辑保留在调用位置,同时让状态保持为普通数据。
import ComposableArchitecture
import SwiftUI
Button("Toggle") {
store.send(.toggleTapped, animation: .default)
}组装视图
完整的 TCA 视图会持有一个 StoreOf,使用点语法读取状态,并从控件发送操作。其余工作由归约器完成,从而让视图保持精简和声明式。
正是这种分离让 TCA 视图易于阅读和预览。
import ComposableArchitecture
import SwiftUI
struct CounterView: View {
let store: StoreOf<CounterFeature>
var body: some View {
VStack {
Text("Count: \(store.count)")
Button("Increment") { store.send(.incrementTapped) }
}
}
}快速检查:驱动界面
请回忆 SwiftUI 视图如何在 TCA 中触发状态变化。
回顾:Store 与 SwiftUI
您已经将一个功能连接到了 SwiftUI:
StoreOf<Feature>保存状态并运行归约器。- 您可以使用初始状态和功能归约器创建 Store。
- 现代观察机制允许您使用点语法读取状态,例如
store.count。 - 视图通过调用
store.send(.action)改变状态,也可以选择传入载荷或动画。 - 旧式的
WithViewStore及其observe闭包会出现在较旧的代码中。
接下来,您将为归约器添加副作用和可注入的依赖。
import ComposableArchitecture
import SwiftUI
// Recap: StoreOf holds state, view reads with dot syntax,
// store.send(.action) drives every change.常见问题解答
「Store 与 SwiftUI 集成」课时是免费的吗?
是的 — 「Store 与 SwiftUI 集成」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「Store 与 SwiftUI 集成」这节课中我会学到什么?
通过 TCA store 驱动视图。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「Store 与 SwiftUI 集成」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。