Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subscribing to only parts of store #2060

Closed
alixander opened this issue Oct 27, 2016 · 5 comments
Closed

Subscribing to only parts of store #2060

alixander opened this issue Oct 27, 2016 · 5 comments

Comments

@alixander
Copy link

alixander commented Oct 27, 2016

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.

@sompylasar
Copy link

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: #1385

@markerikson
Copy link
Contributor

markerikson commented Oct 27, 2016

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 .

@alixander
Copy link
Author

alixander commented Oct 28, 2016

@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.

@markerikson
Copy link
Contributor

markerikson commented Oct 28, 2016

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.

@alixander
Copy link
Author

That makes sense, thank you for the explanation!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants