Currently refactoring Angular application to use ngrx store and have two options. Here's our basic structure of the application. I believe that most Angular applications are built the same way:
AppComponent
|-- ContainerComponent
|-- ChildComponent1
| |-- GrandChildComponent
| |-- GrandGrandChildComponent
|-- ChildComponent2
ContainerComponent has injected Store<AppState>. The problem I'm trying to solve is that GrandGrandChildComponent (say, DropDownMenu component) has to change its behaviour based on the state of the application (i.e. disable some menu items on certain conditions that happen in the store) and emit an event when clicked on menu item so ContainerComponent (or any other component, not necessary ancestor) could react upon it.
There are a couple of ways of solving it:
- Communicate between components using
@Input/@Output - Inject
Storeinto any component that requires knowing the state
Option 1 is what most common/recommended pattern that I've read in the docs. So only ContainerComponent is fat and all children are thin/dumb and relies on the state that comes in through @Input.
But from what I see this approach adds a lot of boilerplate where you have to add unnecessary attributes just to pass-through the state to GrandChild components. And also it breaks the separation of concerns principle because any intermediate components have to know what is required in the components that are below. And it's not easy to make generic component if it knows of the details that are available only on GrandComponents.
On the other hand, approach 2 seems to solve the issue of separating concerns and it also seems to be cleaner implementation. But as I'm relatively new in using redux pattern I'm not sure if that's the way to go and perhaps I don't know any pitfalls that I might face when I'll be too deep in refactoring.
IMO, both approaches provide an easy way of testing of each component which is a huge for me.
I'm in doubt which approach to take. What pitfalls should I be aware of?
Thanks