hydrate
has landed to React 16, but its use isn't documented yet.
This article suggests that it is is supposed to be used with renderToNodeStream
but doesn't give much details.
What is the expected usage of hydrate
?
renderToString
is synchronous. It also cannot handle re-rendered components, i.e. when synchronous (i.e. same tick) changes happen in component state during initial rendering and are supposed to trigger additional render
calls. The example is Helmet that requires a workaround in order to propagate changes from nested Helmet
back to top-level component on server side.
Can hydrate
and renderToNodeStream
help to avoid renderToString
limitations and render asynchronous and/or re-rendered components on server side?
Hydration is the process of using client-side JavaScript to add application state and interactivity to server-rendered HTML. It's a feature of React, one of the underlying tools that make the Gatsby framework. Gatsby uses hydration to transform the static HTML created at build time into a React application.
React hydration is a technique used that is similar to rendering, but instead of having an empty DOM to render all of our react components into, we have a DOM that has already been built, with all our components rendered as HTML.
The render() method of the react-dom package is considered legacy starting react-dom version 18. The method is replaced with the createRoot() method that is exported from react-dom/client . The createRoot() method takes the root element as a parameter and creates a React root.
render renders your components to the DOM while a component's render returns the elements that make up the component.
hydrate
's usage is not limited to renderToNodeStream
- you can (actually should) also use it with the classical renderToString
. renderToNodeStream
is essentially the same as renderToString
with exception that it produces an http stream instead of a string. This means that you can send the rendered html to the client byte by byte during rendering, contrary to the standard renderToString
, when you have to wait for the whole html string to be rendered first, and only after can you send it to the client.
ReactDOM.hydrate
is a replacement for standard ReactDOM.render
. The basic (and only?) difference is that, contrary to ReactDOM.render
, it doesn't throw away all the DOM if React's checksum on the client doesn't match the one calculated on the server. It tries to attach React client app to the server-rendered DOM even if there are some subtle differences, by patching just the differing parts.
Due to the streaming nature of renderToNodeStream
, Helmet's server-side usage is practically impossible in the current state of the library - the head
part of the DOM is sent to the server by the time React get's to compute the DOM including Helmet's components. The stream can't just revert and append Helmet's changes to head
.
So to sum, answering your question - renderToNodeStream
solves the problem of synchronous rendering to string by sending stream, but it introduces new problem of not being able to patch the pushed content if some further part of the React App requires it. It doesn't add anything in terms of state changing and rerendering on the server side. On the other hand, hydrate
doesn't introduce anything new in this topic - it's just a tuned up, more forgiving version of the old render
.
The official docs explain a lot! https://reactjs.org/docs/react-dom.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With