-
I've recently updated ComposableArchitecture from
At first sight, it's hard to guess which part of my code triggers it, because Xcode 14.3.1 (14E300c) provides just the file, without an exact line number. After a brief investigation, I think the problem lays in the following code of my reducers: Reduce { state, action in
// ...
case .binding(\.$query.dateRange): // <-- this line triggers the warning
return .task { .loadInfo }
// ...
} and in my SwiftUI views: struct DashboardFiltersView: View {
let store: StoreOf<DashboardComponent>
struct ViewState: Equatable {
init(state: DashboardComponent.State) {
query = state.query
isLoading = state.isLoading
}
var query: DashboardInfoProvider.Query
var isLoading: Bool
}
public var body: some View {
WithViewStore(store, observe: ViewState.init) { viewStore in
DayRangeFormView(
range: viewStore.binding(
get: \.query.dateRange,
send: { DashboardComponent.Action.set(\.$query.dateRange, $0) } // <-- this line triggers the warning (probably)
)
)
.disabled(viewStore.isLoading)
}
}
} Despite the hints to use Will appreciate support from this amazing community :-) |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
I think I found a way to silence the warnings that appeared in my reducers like this: Before: BindingReducer()
Reduce { state, action in
// ...
case .binding(\.$query.dateRange): // <-- this line triggers the warning
return .task { .loadInfo }
// ...
} After: BindingReducer()
.onChange(of: \.query.dateRange) { _, _ in
Reduce { _, _ in
return .task { .loadInfo }
}
}
Reduce { state, action in
// ...
} I'm not sure if this is the correct way though. It adds tons of boilerplate code, especially in places where I had multiple actions in pattern matching: BindingReducer()
Reduce { state, action in
// ...
case .binding(\.$query.dateRange),
.binding(\.$query.someProperty1),
.binding(\.$query.someProperty2),
.binding(\.$query.someProperty3):
return .task { .loadInfo }
// ...
} becomes: BindingReducer()
.onChange(of: \.query.dateRange) { _, _ in
Reduce { _, _ in
return .task { .loadInfo }
}
}
.onChange(of: \.query.someProperty1) { _, _ in
Reduce { _, _ in
return .task { .loadInfo }
}
}
.onChange(of: \.query.someProperty2) { _, _ in
Reduce { _, _ in
return .task { .loadInfo }
}
}
.onChange(of: \.query.someProperty3) { _, _ in
Reduce { _, _ in
return .task { .loadInfo }
}
}
Reduce { state, action in
// ...
} I still have no idea how to fix the warnings in my SwiftUI views. |
Beta Was this translation helpful? Give feedback.
-
![]() |
Beta Was this translation helpful? Give feedback.
-
Our team is seeing the warning in many files across our app, despite only using binding chaining in 2 views. Some of the warnings are in files that don't even import TCA. Is this expected? |
Beta Was this translation helpful? Give feedback.
We detailed all of these changes in this discussion, but the tldr is that while the previous syntax seemed great, there were a lot of gotchas that you can fall into, and people often did. So we had to change things.
Also, FWIW you should be able to simplify your chain of
onChange
s with something like this:However, it looks like we are missing the
removeDuplicates
variation ofonChange
and so it may be worth adding that. Too bad tuples aren't equatable…