Dependency Inheritance and Overriding Best Practice #1891
-
Suppose I have a parent reducer that contains or navigates to a child reducer, and the parent reducer's body looks something like this: var body: some ReducerProtocol<State, Action> {
Reduce { state, action in
// … parent reducer logic…
}
Scope(state: \.childState, action: /Action.child) {
Child()
}
} Suppose each reducer also has the same dependency, for example: struct CountClient {
var getCount: () -> Int
}
// …
// Parent reducer dependency
@Dependency(\.countClient) var countClient
// …
// Child reducer dependency
@Dependency(\.countClient) var countClient In order to override this dependency, in say a preview, I can use the let store: StoreOf<Parent> = {
let parent = withDependencies {
$0.countClient = CountClient(fetch: { 100 })
} operation: {
Parent()
}
return StoreOf<Parent>(initialState: Parent.State(), reducer: parent)
}() This will correctly override the To make overrides propagate to the child reducer, should the parent's body be something like this? var body: some ReducerProtocol<State, Action> {
Reduce { state, action in
// … parent reducer logic…
}
Scope(state: \.childState, action: /Action.child) {
Child().dependency(\.countClient, self.countClient)
}
} This seems to work, but it means explicitly setting the child's dependency in the parent's body, which seems clunky. Furthermore, if you wanted child reducers to always inherit overridden dependencies from the parent, you'll be configuring your dependencies this way for most of your app's reducer. Finally, if the parent and child don't share a dependency, then it doesn't seem possible to override the child's dependencies at all when instantiating the parent. This makes me think I'm missing something when it comes to overriding dependencies on a hierarchy of reducers. Or maybe I'm running into bugs, or have configured my app incorrectly. I can provide a sample project demonstrating some of this, if it's helpful. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
Hi @TicTocCroc, I believe there are two ways you can fix this. Rather than wrapping the creation of the static var previews: some View {
ParentView(
store: Store(
initialState: Parent.State(),
reducer: Parent()
.dependency(\.countClient, …)
)
)
} And another option is the static var previews: some View {
ParentView(
store: Store(
initialState: Parent.State(),
reducer: Parent()
) {
$0.countClient = …
}
)
} If neither of those options work, then perhaps a sample project would be helpful. |
Beta Was this translation helpful? Give feedback.
Hi @TicTocCroc, I believe there are two ways you can fix this. Rather than wrapping the creation of the
Parent
reducer inwithDependencies
, you should be using the.dependency
reducer operator in the preview:And another option is the
Store
initializer takes a trailing closure that allows you to override dependencies for the entire runtime:If neithe…