Redux: Subscribing to only parts of store

Created on 28 Oct 2016  路  5Comments  路  Source: reduxjs/redux

Connect compares the entire store to the previous version of the store every time it receives an action. Is there a reason why there's no customization to listen to particular parts of the reducer? The advantage is that a whole lot of mapStateToProps could be saved from running in a large app.

For example if the reducer shape is
{A: {a1: '1', a2: '2'}, B: ...}
and I have a component CompA who's mapStateToProps returns a2 value, and B has frequent updates (say for example, updating on scroll position), then CompA's mapStateToProps would also execute on every update. I feel like there's benefits to allowing a comparison in connect to see if A has changed and only call mapStateToProps if it did, especially if we use immutable data structures and a simple equality would work.

Most helpful comment

That makes sense, thank you for the explanation!

All 5 comments

A redux store has just one reducer function that returns the next state given the current state and an action. The "parts" of that state you're talking about are an implementation detail, likely introduced to your mind by the combineReducers helper function, which is in fact optional, though everybody uses it for convenience.

What you might want to do is to "connect" to a set of separate stores, each with its own reducer, dispatch and getState. This way you may gain additional performance by not doing some of the updates, but you are losing the single state object which is helpful if you want to reproduce a certain app state.

See the lengthy discussion here for details and tradeoffs: https://github.com/reactjs/redux/issues/1385

This is a frequently asked-for feature. The answer is that Redux deliberately provides low-level primitives such as store.subscribe(), and others can build more sophisticated logic on top of that.

For connect, that "particular parts of a reducer" idea basically _is_ what mapState does. Any component _could_ be interested in any portion of the state. Redux itself doesn't track what parts of the state may or may not have changed, so it's up to subscribers to do that. With connect and mapState, the approach is to deal with what mapState returns. If a mapState function is only interested in a certain slice, then returning that slice from mapState is the same effect as "subscribing to that slice".

Please see the relevant question in the FAQ: http://redux.js.org/docs/faq/StoreSetup.html#store-setup-subscriptions .

@markerikson
Say you have 200 components and only 1 cares about the scroll updates. So those 200 are going to run mapState each time just to determine their part of the reducer didn't change. To me that's not equivalent to having connect check that their part of the store didn't change with == and not run mapState in the first place for those other 199 components that didn't care about scroll update.

Some part of the code would still be running checks to see whether the relevant slice of state changed. Really, the only question is whether that check is happening inside of dispatch, or outside it.

There are some addons built by the community that add more specific diffing logic on top of the core subscribe primitive, which I have listed in my Redux addons catalog at Store#Store Change Subscriptions.

It's also important to understand the distinction between "reducers" and the state as a whole. As the Structuring Reducers docs point out, you really only have _one_ reducer function: the root reducer that you passed to createStore. From Redux's perspective, that's it. One function, one state value, and no "reducers" to subscribe to. The idea of "reducers" is about how you approach splitting up your update logic for maintainability, not "here is a thing that someone can subscribe to". So, since there's only one state value, it also makes sense that there's only one simple "something has changed" event as well, and it's up to subscribers to figure out if it's relevant to them.

That makes sense, thank you for the explanation!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mickeyreiss-visor picture mickeyreiss-visor  路  3Comments

parallelthought picture parallelthought  路  3Comments

timdorr picture timdorr  路  3Comments

ms88privat picture ms88privat  路  3Comments

CellOcean picture CellOcean  路  3Comments