-
Notifications
You must be signed in to change notification settings - Fork 47.3k
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
#5473 warn and ignore setState and forceUpdate calls if rendered on server #5879
Conversation
I think we can't ignore Also, we should think through the cases where |
- isServerSideRendered is either 'false' or an object with a 'isAfterComponentWillMount' flag; - setState() method calls executed after componentWillMount() (e.g. setTimeout() callback) are ignored if component was rendered on server. All setState() calls during componentWillMount() are allowed; - all forceUpdate() method calls are ignored if component was rendered on server; - restored 'allows setState in componentWillMount without using DOM' test.
@mdolbin updated the pull request. |
@jimfb As far as I know the only use of state in case of server-side rendering is a one-time initial rendering itself, isn't it? |
Yeah, I think I agree with you. cc @spicyj |
'if component was rendered on server.'; | ||
jest.runAllTimers(); | ||
expect(setTimeout.mock.calls.length).toBe(1); | ||
expect(console.error.calls.length).toBe(2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably add a boolean so we only emit the warning once (otherwise the user's logs might fill up with this message).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jimfb I saw this pattern a lot of times, but it seems like it would be much easier to rework an abstract component as a whole if we know about all warnings at once (which can be delayed in time), instead of discovering them one by one. IMHO
Anyways, let me know if we still want to stick to the first warning only policy. I'll just add one more property to the _serverSideRendered
object in that case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We generally stick to warn-once where possible/practical, because otherwise a warning that fires often can drown out a warning that only fires infrequently (which results in people not seeing the less-frequent warning).
Let's add a global boolean instead of using _serverSideRendered, since the latter will be thrown away each render.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense
Overall, I think this is good. A couple of minor notes, then I think we can squash the commits together and merge. |
Hmm. I thought we were going to start using ReactNoopUpdateQueue for server rendering instead of ReactUpdateQueue and in that case it would be easy to swap out an implementation that warns for server rendering. Really that would be a much cleaner solution than this. Also, if we do go with this solution, please use ReactInstanceMap instead of |
Cool, thanks |
- fire a single warning for all components; - this._reactInternalInstance => ReactInstanceMap.get(this); - _isServerSideRendered => _serverSideRendered; - updated tests.
@mdolbin updated the pull request. |
1 similar comment
@mdolbin updated the pull request. |
Looks good to me. I'll leave it open for another day in case there are any other feedbacks, and then we can merge. |
Oh, but please do squash the commits before we merge. You can do this using |
There should not be logic about server rendering in src/isomorphic. It is a concept specific to the DOM renderer. |
@jimfb sure, sorry, a lot of work these days. |
@spicyj, any ideas on where you'd like the code to live? |
Like I suggested originally, we should change to use ReactNoopUpdateQueue on the server, which would probably mean having queue come from the transaction (since that differs between client and server rendering). Also open to other ideas but that's what I suggested 3 months ago and it's still the best option that I see. |
I’m closing as this has been inactive for quite a few months but please leave another comment in #5473 and open a new PR if you’d like to work on this again! Thanks for your time. |
@gaearon I'm going to start to find a fix, but don't expect much. Do you mind providing as much info as you got on this issue? Been looking at how client side renders updates, were you thinking of involving |
I think the problem is that To fix the problem, instead of In I hope this helps! |
@ev1stensberg: sorry, seems that we started working on that at the same time. I have something on https://github.com/rricard/react/tree/fix-5473. I still have no tests so the PR is not complete yet (and I still need to fix two other failing tests), maybe we could work on that together, or if you can finish this PR faster than me, please feel free to use what I did! |
@rricard No worries, we are after the same thing here 😄 I'm busy 0400-1800 every day this summer, so I doubt I'll be done before you. |
@ev1stensberg: cool! The PR is here if you are interested: #7127 |
@rricard Looks like you manage well on your own! |
As discussed in the #5473: