-
Notifications
You must be signed in to change notification settings - Fork 47.2k
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
Add ReactDOM.hydrate() as explicit SSR hydration API #10339
Conversation
286f6a4
to
965217d
Compare
Updated to add deprecation messages and expanded tests for both APIs while we support them. |
6ac1772
to
4096c75
Compare
{'Hello ' + this.props.hello} | ||
</body> | ||
</html> | ||
describe('with old implicit hydration API', () => { |
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.
I copy pasted these tests into two separate groups.
One still calls render()
and, for cases where markup is reused, we verify that in Fiber mode we print a deprecation. We can delete this group of tests in 17.
Another calls hydrate()
and we don’t expect deprecations there. The new version also removes non-Fiber branches since hydrate()
only exists in Fiber.
@@ -305,7 +305,6 @@ function createOpenTagMarkup( | |||
if (isRootElement) { | |||
ret += ' ' + DOMMarkupOperations.createMarkupForRoot(); | |||
} | |||
ret += ' ' + DOMMarkupOperations.createMarkupForID(''); |
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.
If we remove this then we break existing usage of ReactDOM.render and have no way of showing the warning, no?
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.
Isn't the data-reactroot
attribute enough for detection?
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.
I think this changes the behavior if you try to ReactDOM.render
into a non-container. But maybe that's fine?
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.
What is a non-container?
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.
A child of the container. The React root is the first child of the container. It also has children. You're not supported to render into those.
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.
I'm too hungry to think about what happens with non-containers. It's probably fine because you'd have a warning in 15.
4fc2346
to
3c0a6cf
Compare
warning( | ||
false, | ||
'hydrate(): Expected to hydrate from server-rendered markup, but the passed ' + | ||
'DOM container node was empty. React will create the DOM from scratch.', |
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.
IMO we should revert this warning since it's valid to have an empty container if your server rendered ""
, null
, false
or []
at the root. You'll get a warning about hydration being a non-match later anyway, if it's not. We can potentially special case the bulk error message in #10085 if the only diff was that the container was empty.
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.
Ah okay. Will do.
First attempt at #10189.
data-reactid
from new SSR.data-reactroot
as heuristic for hydration.ReactDOM.hydrate()
API that never clears the existing content.ReactDOM.render()
will now print a deprecation message when it tries to reuse markup.lowPriorityWarning
.This means
ReactDOM.render()
would still attempt to hydrate when there’s an element root, but might not work for new features (like top level strings or fragments).ReactDOM.hydrate()
would always hydrate.I have switched the integration test to use the new hydration API when available, and this let me remove the special case for top level text nodes that I added in #10333.