Reconsider deprecation of .binding(action:)
#1150
lukeredpath
started this conversation in
Ideas
Replies: 1 comment 4 replies
-
Hey @lukeredpath, I've had situations similar to this where I've wanted to just use I'd normally introduce a few helpers: enum BindableActionOf<State>: BindableAction { case binding(BindingAction<State>) }
extension Reducer {
public static func binding<LocalState>(
state toLocalState: CasePath<State, LocalState>,
action toLocalAction: CasePath<Action, BindingAction<LocalState>>
) -> Self {
let reducer = Reducer<LocalState, BindableActionOf<LocalState>, Void>.empty.binding()
return Reducer<LocalState, BindingAction<LocalState>, Void> { state, action, _ in
_ = reducer.run(&state, .binding(action), ())
return .none
}
.pullback(state: toLocalState, action: toLocalAction, environment: { _ in })
}
public func binding<LocalState>(
state toLocalState: CasePath<State, LocalState>,
action toLocalAction: CasePath<Action, BindingAction<LocalState>>
) -> Self {
self.combined(with: .binding(state: toLocalState, action: toLocalAction))
}
}
extension ViewStore {
public func binding<Value: Equatable>(
_ keyPath: WritableKeyPath<State, BindableState<Value>>
) -> Binding<Value> where Action == BindingAction<State> {
self.binding(get: { $0[keyPath: keyPath].wrappedValue }, send: { .set(keyPath, $0) })
}
}
Your example could then be something like this: let subsectionReducer = Reducer<SubsectionState, FormAction, Void>.combine(
.binding(state: /SubsectionState.one, action: /FormAction.one),
.binding(state: /SubsectionState.two, action: /FormAction.two)
)
This is what I end up doing more often though. If |
Beta Was this translation helpful? Give feedback.
4 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
When
BindableAction
was introduced, the overload of.binding
that takes an explicit extract function was deprecated. I think there are still valid use cases for this overload, specifically in situations where you might need to be able to handle multiple different binding actions over different sub-state within the same reducer.For instance, imagine a form that has some dynamic section which can change depending on some other property of the form state - maybe you select from a range of values in one section of the form and depending on your selection, a different sub-section of the form is shown or hidden.
Each of these sub-sections have their own state which in this example is driven entirely by bindable state:
What I'd ideally like to do is have a single
FormAction
with a case for each binding action:I could then define a reducer for each section as:
And a reducer for the entire subsection state as:
Because
binding(action:)
is deprecated, I would instead need to create a separate sub-action enum for each section with a singlebinding
case that I could conform toBindableAction
which adds extra boilerplate and makes the pullbacks more complicated than they need to be.Would it be possible to "undeprecate" this action?
Beta Was this translation helpful? Give feedback.
All reactions