Comments (31)
I think of it as a matter of grouping related code or concerns together. In contrast, consider an approach like Relay's where many components are connected and the components and their data requirements (ex: a Redux selector or Relay query) exhibit high cohesion.
Imagine if a site like GitHub were implemented with Redux and React. The component hierarchy would likely be many levels deep. For example, the IssueCommentHeader component would be quite far away from the root component. If only the root component were connected to the store, the root would need to know that the IssueCommentHeader—very far away—needs the user's username and profile picture.
What if you change IssueCommentHeader so that it needs the user's online/offline presence, like a chat app? Now you need to modify IssueCommentHeader's owner, and its owner, and so on until you've modified every component up to the root so that it threads the user's presence data down this deep component hierarchy.
In summary it's not scalable for your productivity, let alone a team's productivity, to put all of the data-retrieving functionality in the root component. This was a real problem when building the liking & commenting UI on Facebook—it looks like a small component but there's a lot of complexity hiding inside it and for its root component to need to know all the data wanted by its leaves deep down was hard to write code for and maintain. What we really wanted is for components at many levels of the hierarchy to specify the data they needed so that related code was grouped together.
from redux.
I researched these questions by Dan himself (on S.O.) and users of Redux grappling with the same exact issue, so I am glad I'm not the first to ask.
I think the answer on S.O. is not ideal... leaving it to the programmer is not a cozy solution
@gaearon have you any updated insight?
from redux.
@gaearon Here ya go! https://github.com/acdlite/redux-batched-updates
from redux.
Thanks for posting this. Keeping this open for now. I'll revisit after ReactEurope.
If somebody wants to help tackle this please write here :-)
from redux.
If you run into someone from Relay it could be good to get their input since this is the kind of performance problem faced by a big website with many components reading from the same stores.
from redux.
@ide some good thoughts there, it would definitely be a welcome improvement, as performance increases are always a good thing :)
from redux.
If you run into someone from Relay it could be good to get their input since this is the kind of performance problem faced by a big website with many components reading from the same stores.
Related: facebook/react#3920 (comment)
from redux.
Can't we just wrap the subscription notification in React.addons.batchedUpdates
by the way?
from redux.
@ide that's what you suggested to me the other day in regard to flummox, right?
from redux.
I don't know the behavior of batchedUpdates across components though it may solve this problem. Will have to look at its source.
In flummox's case one component might subscribe to multiple stores that each emit a change in response to the same action, so batching that component's setState calls is useful. With redux components have just one subscription to the redux instance and all the stores update before the component is notified once per action.
from redux.
I don't know the behavior of batchedUpdates across components though it may solve this problem. Will have to look at its source.
It reaches into React's internals and tells it that setState
shouldn't immediately update but instead should wait until the callback is over. This is exactly what React already does when dispatching DOM events.
Isn't this the kind of thing you were talking about? Both parent and child are invalidated, but the DOM changes are not cascading and instead applied in one pass.
Perhaps @spicyj can confirm if that's indeed how batchedUpdates
works.
from redux.
Yes, that's what batchedUpdates does. Parents will reconcile first so that the children render only once (with the newest props from their parent and their newest state).
from redux.
Thanks!
The un-nice thing about it is that it's an addon, which means we can't get it from React
. We can't get the internal ReactUpdates
from React
either. Ugh..
I wonder if 0.14 solves that somehow.
from redux.
You'll be able to require react/addons/batchedUpdates
(and avoid packaging the other addons) but there's no way to get it from the React object, sorry. I think @sebmarkbage may have wanted to move it to React
sometime though?
from redux.
Can a library depend on anything from react/addons/*
? I think that wouldn't work if the user aliases react
to a precompiled file, would it?
from redux.
That's right, it wouldn't.
from redux.
It's unfortunate batchedUpdates
is not on React
itself then. An addon by definition, in my opinion, should be implementable outside the library, but batchedUpdates
is privileged to expose an internal.
from redux.
We think of it slightly differently – addons use React internals (which is why we package them at all instead of letting someone else write it), but their API is liable to change more frequently.
from redux.
OK, thanks for explaining!
from redux.
Parents will reconcile first so that the children render only once (with the newest props from their parent and their newest state).
Cool - sounds like batchedUpdates addresses this then.
I made a little demo with two nested components that read the same store data and to my surprise the updates already appear batched (the child gets its new props and new state together). https://gist.github.com/ide/1da8a70a14535835da30
from redux.
@ide I think this is because React batches updates coming from events by default.
@acdlite Sounds like batchedUpdates
is a great fit for a middleware that wraps inner dispatch
calls in it.
from redux.
@gaearon Would there be any downside in a middleware that wraps all dispatches in batchedUpdates?
from redux.
@acdlite I don't think so, that's what I'd do.
from redux.
@gaearon You're right -- React Native wasn't the best environment to test in because it batches messages from the bridge :P
from redux.
@ide React will also batch for DOM events. But it won't for AJAX callbacks etc.
from redux.
NuclearJS just added a batch()
function, since React was previously notified after EVERY action: optimizely/nuclear-js@de35e19
from redux.
There are some unsolved issues with batching such as with controlled components. The plan is likely to move to batching by default with an opt-out for difficult cases.
from redux.
@sebmarkbage Great to hear, that sounds sensible.
Closing this since the extension I posted above addresses the issue.
from redux.
On second thought let's keep this open until we have docs surrounding it.
from redux.
Added to docs in 13058f0.
from redux.
@ide @gaearon i know this is closed but for educational purposes what are the reasons someone would want to connect the child components rather than push the root parent state as props down the component tree? This way only the root parent is connected. This is heirarchical composition, so descendants should all be stateless components, no? For example, a calendar date selection component would have one stateful parent and a bunch of stateless components as descendants. Connected state is pushed down via read only props from calendar elemt root component to the statelsss descendants. What am I missing?
from redux.
Related Issues (20)
- TS conflict between AppThunk and createAsyncThunk.withTypes HOT 2
- CodeSandbox is broken HOT 2
- Store state lost when page refresh HOT 1
- Using useSelector reload required to get updated value of state HOT 1
- providesTags does not work with callback when defining return type via TypeScript generic HOT 4
- [email protected]: Empty object check error HOT 4
- Math.random() usage HOT 3
- Instead of Why there should What HOT 1
- Missing link in Learning Resources -> Middleware
- updating redux from 5.0.0 to 5.0.1 Typescript errors HOT 18
- Could “ plain” class instances be stored in Redux store state. HOT 15
- Update copyright HOT 1
- Invalid external image link
- Small inconsistant in the docs: src/app/ or app/? HOT 2
- Redux core example app not working HOT 1
- Add combineSlices section to Code Splitting page
- doc not match in setup with nextjs HOT 1
- The wrong export in redux/examples/counter-ts/src/features/counter/counterSlice.ts HOT 1
- remove references to deprecated createStore
- Redux import type gone since upgrading to latest version with javascript (Next 14) HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from redux.