Search code examples
htmlangulartypescriptngrx

Should a component manage the state(s) of sub-components in ngrx/store?


I am trying to determine the best practice for state management. That is, whether the parent of 2 subcomponents should manage the state for those subcomponents.

For example:

<div>
    <subcomponent-one> *ngIf="condition"></subcomponent-one>
    <subcomponent-two> *ngIf="!condition"></subcomponent-one>
</div>

And inside each subcomponent, various ngrx actions can be dispatched. However, a certain action may lead to the condition: bool being changed.

So the question is: should the state be shared across both components? And, should this state be managed by the parent?


Solution

  • I tend to suggest the "container/presenter" pattern, which is almost exactly what you have proposed here.

    Your parent ("container" or "smart") connects to the store, generally creating a bunch of Observables whose values it passes to its children ("presenters" or "dumb" components) via the async pipe.

    (Do not subscribe to the Observables and store their emissions in local variables. I see this happen far too often and it is a horrendous anti-pattern.)

    Depending on how your app is set up, I would also suggest that instead of dispatching actions from your children, use @Output and react to those events in the smart parent.

    This pattern allows you to separate store logic from display logic, leading to a much tidier and more modular app.

    <div>
        <subcomponent-one> *ngIf="condition$ | async"></subcomponent-one>
        <subcomponent-two> *ngIf="inverseCondition$ | async"></subcomponent-one>
    </div>