-
Assuming my state looks like this: typealias BarId = Tagged<Bar, String>
struct BarState: Identifiable {
var id: BarId
var x: Int
}
struct FooState {
var barStates: IdentifiedArrayOf<Bar>
} And I have a dependency protocol BazType {
func getX(for id: BarId) -> Int
} My struct BarFeature: Reducer {
typealias State = BarState
enum Action {
case getX
case setX(Int)
}
var id: BarId
@Dependency(\.baz)
var baz
var body: ReducerOf<Self> {
Reduce { state, action in
switch action {
case .baz:
return Effect.run { send in
let x await baz.getX(for: id)
send(.setX(x))
}
}
}
}
} Now I would like to use it in my struct FooFeature: Reducer {
struct State = FooState
enum Action {
case bar(BarFeature.Action)
}
var body: some ReducerOf<Self> {
EmptyReducer()
.forEach(state: \.barStates, action: /Action.bar) { /* doesn't take any arguments */ in
let id = ... // TODO: Where does this come from?
BarFeature(id: id)
}
}
} I know that I could make Looking into how the So for now I've resorted to implement my own As an alternative to initializing the struct BarSpecificBaz {
func getX() -> Int
} Then I could pass this in from my .forEachWithId(state: \.barStates, action: /Action.bar) { id in
BarFeature(id: id)
.dependency(\. barSpecificBaz, baz.scope(for: id))
} As an alternative to consider, a .forEach(state: \.barStates, action: /Action.bar) {
BarFeature()
}
.transformDependency(\.self) { dependencyValues, action in
dependencyValues.barSpecificBaz = dependencyValues.baz.scope(for: id)
} The syntax of that would be a little more tedious to use, but such a But here it starts getting really hard for me to reason about the internals of TCA and Dependencies. I'm curious to see what others have come up with to handle such scenarios. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi @mrackwitz, I think I'm a little confused with this definition of the reducer: struct BarFeature: Reducer {
typealias State = BarState
var id: BarId
…
} Why does If you got rid of the case .baz:
return .run { [id = state.id] send in
let x = await baz.getX(for: id)
send(.setX(x))
} |
Beta Was this translation helpful? Give feedback.
Hi @mrackwitz, I think I'm a little confused with this definition of the reducer:
Why does
BarFeature
need an ID whenstate.id
is available? Doesn't this even open up the possibilities of invalid data whereself.id != state.id
?If you got rid of the
id
onBarFeature
then you would just use the dependency by accessing the ID directly on state: