-
Greetings everyone.
The code looks like this: import SwiftUI
import ComposableArchitecture
typealias ContentStore = StoreOf<ContentFeature>
typealias ContentState = ContentFeature.State
typealias ContentAction = ContentFeature.Action
struct ContentView: View {
let store: ContentStore
var body: some View {
VStack {
// Doesn't work ❌
SwitchStore(store) { state in
switch state {
case .text:
CaseLet(/ContentState.text, action: ContentAction.text) {
TextView(store: $0)
}
case .data:
CaseLet(/ContentState.data, action: ContentAction.data) {
ListView(store: $0)
}
}
}
// Works ✅
WithViewStore(store) {$0} content: {
switch $0.state {
case let .text(text):
TextView(
store: TextStore(initialState: text, reducer: TextFeature.init)
)
case let .data(data):
ListView(
store: ListStore(initialState: data, reducer: ListFeature.init)
)
}
}
}
}
}
@Reducer
struct ContentFeature {
var body: some ReducerOf<Self> {
EmptyReducer()
}
enum State: Equatable {
case text(TextState)
case data(ListState)
}
enum Action: Equatable {
case text(TextAction)
case data(ListAction)
}
}
// =========== The place where I want to handle BindingState ===========
typealias ListStore = StoreOf<ListFeature>
typealias ListState = ListFeature.State
typealias ListAction = ListFeature.Action
struct ListView: View {
let store: ListStore
var body: some View {
List {
ForEachStore(
store.scope(state: \.rows, action: ListAction.rows)
) {
RowView(store: $0)
}
}
}
}
@Reducer
struct ListFeature {
var body: some ReducerOf<Self> {
Reduce { _, action in
switch action {
case let .rows(.element(_, rowAction)):
switch rowAction {
case .binding(\.$isOn):
print("WOW, IT WORKS")
return .none
default:
return .none
}
}
}.forEach(\.rows, action: \.rows, element: RowFeature.init)
}
struct State: Equatable {
var rows: IdentifiedArrayOf<RowState> = []
}
@CasePathable
enum Action: Equatable {
case rows(IdentifiedActionOf<RowFeature>)
}
}
// =========== Row with BindingState ===========
typealias RowStore = StoreOf<RowFeature>
typealias RowState = RowFeature.State
typealias RowAction = RowFeature.Action
struct RowView: View {
let store: RowStore
var body: some View {
HStack {
WithViewStore(store) { $0 } content: { viewStore in
Toggle(isOn: viewStore.$isOn) {
Text(viewStore.id.uuidString)
}
}
}
}
}
@Reducer
struct RowFeature {
var body: some ReducerOf<Self> {
BindingReducer()
}
struct State: Identifiable, Equatable {
@BindingState var isOn: Bool = false
let id: UUID = UUID()
}
enum Action: BindableAction, Equatable {
case binding(BindingAction<State>)
}
} The part with pic.2023-11-25.at.23.09.53.mp4
I am attaching a small project that I have set aside to solve this problem. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Solved. I forgot to add this code to EmptyReducer()
.ifCaseLet(
/State.data,
action: /Action.data,
then: ListFeature.init
) |
Beta Was this translation helpful? Give feedback.
Solved. I forgot to add this code to
ContentFeature
: