Closed aunz closed 8 years ago
I'm... pretty sure that's wrong on several levels.
First, my understanding is that calling ReactDOM.render() repeatedly starts everything over, rather than taking the existing tree of components and updating it. Second, the comment on stateless components is a POSSIBLE future optimization, not one that exists now. You're reading WAY too much into that.
It's a fine approach for learning but I don't think it scales well.
Instead as soon as you see that component passes props down without using it, we suggest generating a "container" component using connect().
In my Egghead video course (linked from README) I actually build an app rendering from the top, and later introduce container components precisely to decrease this coupling. These videos contain instructions on when it's best to do this.
First, my understanding is that calling ReactDOM.render() repeatedly starts everything over, rather than taking the existing tree of components and updating it
No, it reconciles the existing tree, just like calling setState. But it's still slower than setState somewhere in the middle because it has more to reconcile.
:+1:
Hey,
Because JS is not immutable by default, it has been decided that the functional components do not optimize with something akin to PureRenderMixin
by default (but we may be able to in the future).
So your pure functional components will generally be slower than regular classes with an appropriate shouldComponentUpdate
method. This has surprised me as well. React issue
I have been running an app for 1.5 years in production. We built a framework that looks quite similar to Redux, even before Flux came out, but with a badly designed API and also using some cursors (we will migrate to redux or ELM at some point). We don't have connect
or things like that, we always render from the very top exactly like you propose. You can read more here
Even on text inputs, on every keystroke, we don't use this.setState
but actually renders from the very top a new state. You can see this in this video
Here are some feedbacks:
setState
for performance reasons for very local state like text inputs, .hover classes etc...Just to illustrate the mess it created for us, here is our real legacy layout top-level component. Over time it has become a real mess, and just imagine that on every text input keystroke it has to re-render :D layout.jsx
Where we are moving now: having layout components and context providers at the root of the tree. Generally these don't change often:
In most cases, you don't need to re-render these components when your state change.
However there are some cases when the layout still need to change according to state, like when you have a property "menuFolded": you can get it with connect
Then on your layout you put widgets. A widget is an autonomous component that has its own reducer, use something like "connect" to get the state of that reducer. The widget only re-renders when its state changes. I try to make the widget only receive its own state, to make it really independant but it is really a mater of taste and many don't adopt a similar approach and assume the widget should have a global knowledge of the global appstate to select the state it needs to use.
@slorber thanks a lot! Very helpful! Have a :tea:
So we're using this same basic layout in a production application, so I can provide a little 'real world' feedback. About 10 months into dev and 6 months into production at this point. Sorry for the thread necromancy, but I felt the need to add to this.
First, we aren't dealing with any efficiency/performance issues at the moment. We're using seamless-immutable and thinking a fair bit about the draw cycle (react render step) during our design and coding, but we've found that system performance is still high enough that it hasn't yet been a meaningful limit for us. Even on old phones.
We're looking at purity as a way to get more efficient, but since we're not struggling there that keeps dropping in priority.
We aren't using time travel. It looks cool and all... we just haven't found a use case for it yet.
We got into prod real fast. I think that's more to modern JS in general, but it was still a big win with us.
When 100% of the dom is derived from the state at the moment it's pretty cool/fun. Time travel is really fun to watch, but also useful for things like debugging. Grabbing a snapshot of the state to deal with problems has become something of a standard for us, and a pleasant one at that.
Trapping everything meaningful in a dispatch to the same state makes user behavior easy to watch. For our purposes that means it is easy to audit for legal reasons, but it may have other uses for other teams.
It's so testable! That's really what motivated us to try this arrangement, and it hasn't disappointed. I cannot stress enough how wonderful this is. For me it justifies everything else.
It's so compartmental. When we work on reducers, actions, or components we don't feel much, if any, coupling with the others. Mentally this feels, at least right now, like it makes it "easier to code" at least for us.
It's hard to onboard and train. This architecture is so unintuitive to new CS grads and even to more experienced developers from other worlds (in our case java) that it is really affecting our onboarding.
It breaks compatibility with a lot of libraries. Much of the React ecosystem requires at least one stateful component.
We're loving it, but it feels like the bleeding edge and has a few related drawbacks. There are also a lot of unanswered questions about what will happen to the ecosystem in the long run.
@suni-masuno I would be very curious to hear your feedback on this some 16 months later. Do you still agree with all of your pros and cons? What has changed in this time?
@suni-masuno I’m also very interested to hear if your pros and cons have changed and if it still feels like the bleeding edge.
Redux is awesome!
I am wondering if this is a good idea: use Redux at the top, with
store.subscribe
to listen tostore.dispatch
, then aggregate result withstore.getState()
and finally callReactDom.render
. All the Reacts components are written only using stateless functions.So each time a
store.dispatch
is called, ReactDom will render the whole tree again. Essentially, all the components are "dumb", they get the props from Reduxstore.getState()
.What are the pros and cons of this usage?
My limited understanding is that "stateless components can follow a faster code path within the React core" and will be further optimised in the future so performance will not be an issue even without the Lifecycle API such as
shouldComponentUpdate
. Is this correct?Since Redux's principle is not to mutate the state, so calling ReactDom.render each time with a new state (in contrast to using
this.setState({})
insides a React Component) is a better fit with the concept or principle of immutability?The other advantage is that the app can be written without using
this
, withoutclass
norextends
, all pure functionsThanks a lot!