Parent-Child Relationship with Shared Child Views

I'm pretty new to TCA and I was using it for an app that have complex navigation flow and faced this scenario.
I have an AppView that is the root of the app along with its Store and Reducer. Under App View, there is SideNavigationBar along with several modules like Home , Audio and Downloads.

I have this navigation flow:
Home > ItemDetails > AudioDetails
Home > AudioDetails
Home > Search> AudioDetails

As you can see, I can navigate to the audio screen using 3 different paths. The user can download the audio, for which I handle the action in the AppReducer:

AnyReducer<AppState, AppAction, AppEnvironment> { state, action, env in
switch action {
  case .home(.itemDetails(.audioDetails(.downloadPressed))), 
        .home(.audioDetails(.downloadPressed)),
        .home(.search(.audioDetails(.downloadPressed))):
    // Handling Download action.
  }
}

I need to write 3 different cases to handle the download action for the same screen but for 3 different paths, I have other screens as well, so you can imagine how many cases I have to write. I feel like I'm not doing it right. Is there a way to map child action to parent more efficiently?

Hi @ramywagdyrizkalla ! You’re doing it right, that’s the proper way to implement case actions from child reducers in a parent reducer. :ok_hand:

I’ve also noticed that you’re using the old reducer API, so once you`re working with TCA not for too long, I’d really suggest starting using the Reducer Protocol instead.

You can also always implement high-order reducers, but maybe it could be a kind of next level of understanding the architecture logic. You can take a look at this pretty simple high-order reducer of mine to have a glimpse of how it works.

And, of course, if you're a PointFree subscriber you can watch this very episode about high-order reducers to learn more about it from the TCA creators.

Another approach (recently often recommended) for situation where some state/behaviours are shared across multiple features located on separated "branches" is to create communication flow through specialised client. Reasoning behind this is that heavily shared state/behaviour is not much different than accessing database or file system.

It's especially convenient when you use new protocol based reducers with client shared via DependecyValues.

Personally I don't have much experience with setup like this, but it's really often recommended recently.

3 Likes