Angular + NGRX Architecture: When To Use Component State Vs NGRX State
How do you decide when a piece of information should go in your NGRX store, as opposed to being maintained as local component variables?
In General, Reserve Component State For Component-Specific Information
In general, you’ll usually want to persist information on a component when it’s relevant only to that component, and occasionally to its immediate child. Things which are used in many different places, across a deeply nested component tree, or are otherwise global in scope are generally better suited for your NGRX store. It’s also very useful to maintain the state of asynchronous operations in state if you’re using NGRX Effects (such as thingAFetchInProcess
or thingBSaveInProgress
).
However, there are exceptions to this in the form of component-specific information which is still useful to be managed via the store.
Use The Store For Component-Specific Information When
- Component-specific data needs to be projected or transformed in one way or another in relation to data which exists in the store.
- For example, if you’re performing a client-side text filter against information which exists in your NGRX store, then storing your filter text in your NGRX store allows you to offload the filter logic to your selectors, thus keeping your component clean.
- You need to change something in response to an action.
- For example, if you want to show a spinner in a modal while a save operation is in progress and then close the modal on success, then you might want to persist the
showSaveModal
boolean property in your NGRX store, even if it’s only relevant to that component, because it’s much easier and cleaner to close it in yoursaveSucceeded
reducer block than by subscribing to the action stream in your component.
- For example, if you want to show a spinner in a modal while a save operation is in progress and then close the modal on success, then you might want to persist the
Taking Inspiration From redux.js.org
Lately I’ve been finding that many of the deep architectural design questions that I’ve had difficulty finding answers for while Googling in terms of "NGRX" specifically are actually answered fairly well by the FAQ section on redux.js.org. The underlying technology stack and implementation details are different, but the overarching architectural guidance and best practices guidelines are oftentimes very relevant and helpful to anybody using the Redux pattern, including NGRX.
That applies to this question as well as many others. To quote from this question on their FAQ:
Using local component state is fine. As a developer, it is your job to determine what kinds of state make up your application, and where each piece of state should live. Find a balance that works for you, and go with it.
Some common rules of thumb for determining what kind of data should be put into Redux:
- Do other parts of the application care about this data?
- Do you need to be able to create further derived data based on this original data?
- Is the same data being used to drive multiple components?
- Is there value to you in being able to restore this state to a given point in time (ie, time travel debugging)?
- Do you want to cache the data (ie, use what’s in state if it’s already there instead of re-requesting it)?