Files
swift-composable-architectu…/Examples/CaseStudies/SwiftUICaseStudies/01-GettingStarted-Composition-TwoCounters.swift
Stephen Celis 7e3d0e2c51 Clean up examples (#2754)
* Update examples

- Use `#Preview` macro
- Remove superfluous `// MARK` comments

* Simplify case studies

Prefer simple `StoreOf` declaration in case study views

* update some outdated descriptions

* wip

* wip
2024-01-31 16:08:52 -08:00

69 lines
1.4 KiB
Swift

import ComposableArchitecture
import SwiftUI
private let readMe = """
This screen demonstrates how to take small features and compose them into bigger ones using \
reducer builders and the `Scope` reducer, as well as the `scope` operator on stores.
It reuses the domain of the counter screen and embeds it, twice, in a larger domain.
"""
@Reducer
struct TwoCounters {
@ObservableState
struct State: Equatable {
var counter1 = Counter.State()
var counter2 = Counter.State()
}
enum Action {
case counter1(Counter.Action)
case counter2(Counter.Action)
}
var body: some Reducer<State, Action> {
Scope(state: \.counter1, action: \.counter1) {
Counter()
}
Scope(state: \.counter2, action: \.counter2) {
Counter()
}
}
}
struct TwoCountersView: View {
let store: StoreOf<TwoCounters>
var body: some View {
Form {
Section {
AboutView(readMe: readMe)
}
HStack {
Text("Counter 1")
Spacer()
CounterView(store: store.scope(state: \.counter1, action: \.counter1))
}
HStack {
Text("Counter 2")
Spacer()
CounterView(store: store.scope(state: \.counter2, action: \.counter2))
}
}
.buttonStyle(.borderless)
.navigationTitle("Two counters demo")
}
}
#Preview {
NavigationStack {
TwoCountersView(
store: Store(initialState: TwoCounters.State()) {
TwoCounters()
}
)
}
}