Adaptation of ViewStore Binding in SwiftUI 1.7 Migration #3086
-
I've reviewed the documentation I've been using the following code snippet, but it seems that viewStore.binding has been removed with the update to SwiftUI 1.7. How can I replace it? Additionally, considering the necessity to keep child views pure SwiftUI (eg. XXSection, XXCheckBox)
|
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 5 replies
-
Have you migrated to |
Beta Was this translation helpful? Give feedback.
-
Looks like that information is missing from the guide. Opened #3087 to address, but here's an example: Note that if you want test coverage on the logic in custom bindings, you can refactor this logic into the reducer. |
Beta Was this translation helpful? Give feedback.
-
Thank you for your help. There are a few issues: issue 1When using subscript's get without state in the 'subscript' section, Cannot find 'featureFlags' in scope error occurs.
|
Beta Was this translation helpful? Give feedback.
-
Hey there! I created a quick example: // MARK: - Feature
@Reducer
struct Feature {
@ObservableState
struct State {
var isToggleOn: Bool = false
}
enum Action: ViewAction {
case view(View)
// MARK: Internal
enum View {
case didAppear
case didToggle(Bool)
}
}
var body: some Reducer<State, Action> {
Reduce { state, action in
switch action {
case .view(.didAppear):
return .none
case let .view(.didToggle(isOn)):
state.isToggleOn = isOn
return .none
}
}
}
} // MARK: - FeatureViewState
struct FeatureViewState {
// MARK: Lifecycle
init(state: Feature.State) {
toggleTitleText = state.isToggleOn ? "Switch is on" : "Switch is off"
isToggleOn = state.isToggleOn
}
// MARK: Internal
let isToggleOn: Bool
let toggleTitleText: String
} // MARK: - FeatureView
@ViewAction(for: Feature.self)
struct FeatureView: View {
@Bindable var store: StoreOf<Feature>
var body: some View {
let viewState = FeatureViewState(state: store.state)
List {
// ❌ doesn't compile... cannot use .didToggle directly from the view actions
Toggle(
isOn: $store.isToggleOn.sending(\.didToggle),
label: {
Text(viewState.toggleTitleText)
}
)
}
.task {
// I can directly access to the ViewAction here without issue
await send(.didAppear).finish()
}
}
} Does anyone know if I'm doing something wrong? Finally, I wonder if there is a way to use let viewState = FeatureViewState(state: store.state)
List {
// ❌ doesn't work, but looking for something similar
Toggle(
isOn: $store.binding(
get: { viewState.isToggleOn },
set: { status in send(.didToggle(status)) }
),
label: {
Text(viewState.toggleTitleText)
}
)
} In the meantime, I think I could use the proposed extension StoreOf<Feature> {
var isToggleOn: Bool {
get {
let viewState = FeatureViewState(state: state)
return viewState.isToggleOn
}
set {
send(.view(.didToggle(newValue)))
}
}
} Thank you in advance :) |
Beta Was this translation helpful? Give feedback.
Looks like that information is missing from the guide. Opened #3087 to address, but here's an example:
Note that if you want test coverage on the logic in custom bindings, you can refactor this logic into the reducer.