You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI与Composable Architecture(TCA):如何集成子Reducer?

TCA父Reducer与子Reducer集成解决方案

你的核心问题是没有正确利用TCA的Reducer组合机制,不需要手动在Reduce闭包里更新子state,而是通过Scope将子Reducer嵌入父Reducer中,同时在View层通过scope方法传递对应子模块的Store。

1. 修正AppReducer的Reducer组合

修改AppReducer的body,使用Scope将子Reducer与父Reducer关联,自动处理state映射和action转发:

import ComposableArchitecture

@Reducer
struct AppReducer {
    struct State: Equatable {
        var parentState = ParentReducer.State()
        var childState = ChildReducer.State()
    }
    
    enum Action {
        case parent(ParentReducer.Action)
        case child(ChildReducer.Action)
    }
    
    var body: some Reducer<State, Action> {
        // 将父Reducer的state和action映射到AppReducer对应的字段
        Scope(state: \.parentState, action: /Action.parent) {
            ParentReducer()
        }
        // 将子Reducer的state和action映射到AppReducer对应的字段
        Scope(state: \.childState, action: /Action.child) {
            ChildReducer()
        }
    }
}

2. 优化View层的Store传递

原View直接传递整个App的Store,不符合TCA的模块化设计,需要通过scope方法生成对应子模块的Store:

修改ParentView

struct ParentView: View {
    let store: StoreOf<AppReducer>
    
    var body: some View {
        // 生成父模块专属的Store
        let parentStore = store.scope(state: \.parentState, action: AppReducer.Action.parent)
        WithViewStore(parentStore, observe: { $0 }) { viewStore in
            VStack(spacing: 16.0) {
                Text("\(viewStore.count)")
                Button {
                    viewStore.send(.increment)
                } label: {
                    Text("INCREMENT")
                        .font(.largeTitle)
                }
                // 生成子模块专属的Store传递给ChildView
                ChildView(store: store.scope(state: \.childState, action: AppReducer.Action.child))
            }
        }
    }
}

修改ChildView

让ChildView只接收子模块的Store,降低耦合:

struct ChildView: View {
    let store: StoreOf<ChildReducer>
    
    var body: some View {
        WithViewStore(store, observe: { $0 }) { viewStore in
            VStack(spacing: 16.0) {
                Text("\(viewStore.count)")
                Button {
                    viewStore.send(.increment)
                } label: {
                    Text("INCREMENT")
                        .font(.largeTitle)
                }
            }
        }
    }
}

关键原理说明

  • Scope(Reducer层):负责将父Reducer的state切片和action分支映射到子Reducer,TCA会自动调用子Reducer处理对应的action并更新state,无需手动赋值。
  • store.scope(View层):从全局Store中生成子模块的专属Store,让View只关注自身需要的state和action,遵循单一职责原则,同时避免不必要的状态监听。

内容的提问来源于stack exchange,提问作者JamesDerrick248

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:06:02