Learn the difference
You see, it’s important to distinguish, and understand the difference between store observables, and http client observables. Both are observables, in the sense that you can subscribe to store dispatch events, as well as, you can subscribe to http calls. What is returned is the important part. In Vuex, I used actions to solely dispatch my http calls, my actions would then update pieces of state upon completion, and my app would update the DOM accordingly without me having to think about it. With @ngrx, I can still use actions to dispatch http calls, and within those actions, I can patch pieces of state, which DOES update the DOM in components that are subscribed to those changes. The problem arises when you have a need to update a component level property from the data returned from the http call. When you tack a
.then onto your Vuex action dispatcher, you get back whatever you’re returning from your action. When you subscribe to a dispatch action in @ngrx, the observable returned is the full store, which is counterintuitive to what you would think if your action is dispatching an http call and the http call is returning a response object. Angular can only go one level deep on observables, which means, the observable data returned in your @ngrx action will never surface to the observable data being subscribed to by your action dispatcher.
Which is why it’s important to understand this difference so that instead of dispatching an action to make an http call when you really need the data returned from the call, you should instead subscribe to the service making the call. This is where our application was running into trouble. We had built it to over-utilize our store so that every call was made in an action, and those actions then updated pieces of state. We were doing this in places where we should have just made the http call directly cause the state was redundant.
Here is the key takeaway, you end up with redundant state when you’re component is dispatching an action, that’s then updating state, and it does this EVERY time the component loads. If other pieces of your application need the state data that the component dispatch fetches, okay, surely there’s a case for doing this. In our application, we were dispatching an action, that fetched a list of results, and the list of results was only used in that one component. Do you see how putting that data in state was entirely redundant? We could have achieved the same thing with a BehaviorSubject on the component that was updated on the successful http call.
State is powerful, but learning to use it correctly is important to use it effectively. If you plan on using Redux on your project, make sure you’re being intentional with the way you’re architecting your store. It can be very easy to throw every property in your application into a store just cause you think Redux is cool and hip. Instead, I suggest only using your store for pieces of state that have to be accessible across your entire application. A very good example of a crucial state is authentication. Authentication is important across your entire application, put it in the store. Another example is any kind of state related to the application’s layout. Is the drawer open? I don’t know, but it’s easy to check from anywhere if the toggle property is in a store.
At the end of the day, be intentional with your store, don’t overuse state, when services and subjects are equally as effective.