Si te encuentras con alguna parte que no comprendes puedes dejarlo en los comentarios y te responderemos tan rápido como podamos.
Solución:
De los documentos de ReactDOMServer (el énfasis es mío):
Si llamas
ReactDOM.hydrate()
en un nodo que ya tiene este marcado generado por el servidor, React lo preservará y solo adjuntará controladores de eventos, lo que le permite tener una experiencia de primera carga muy eficaz.
El texto en negrita es la principal diferencia. render
puede cambiar su nodo si hay una diferencia entre el DOM inicial y el DOM actual. hydrate
solo adjuntará controladores de eventos.
Del problema de Github que introdujo hydrate
como una API separada:
Si este es su DOM inicial:
Loading...
y luego llamar:
ReactDOM.render(
App
,
document.getElementById('container')
)
con la intención de hacer un renderizado solo del lado del cliente (no hidratación). Entonces terminas con
App
Porque no arreglamos el attributes.
Solo para su información, la razón por la que no parchearon el attributes es
… Esto sería muy lento para hidratarse en el modo de hidratación normal y ralentizaría el procesamiento inicial en un árbol sin SSR.
Hydrate se usa básicamente en el caso de SSR (renderización del lado del servidor). SSR le brinda el esqueleto o el marcado HTML que se envía desde un servidor para que, por primera vez, cuando se cargue su página, no esté en blanco y los robots de los motores de búsqueda puedan indexarlo para SEO (un caso de uso de SSR). Entonces hydrate agrega el JS a su página o un nodo al que se aplica SSR. Para que tu página responda a los eventos realizados por el usuario.
Render se utiliza para renderizar el componente en el navegador del lado del cliente. Además, si intenta reemplazar el hidrato con render, recibirá una advertencia de que el renderizado está obsoleto y no se puede usar en caso de SSR. se eliminó debido a que es lento en comparación con la hidratación.
No tengo nada específico que agregar a lo que se dijo anteriormente sobre el uso de hydrate
, pero al tratar de aprender al respecto, preparé un pequeño ejemplo, así que aquí está el trabajo para quien lo encuentre útil.
Objetivo
Sirva dos páginas, una que usa ReactDOM.hydrate
y uno que usa ReactDOM.render
. Dependerán de algunos componentes de reacción escritos en JSX, que son cargados por tags, given artificial delay (by the server) to illustrate the difference between
hydrate
and render
.
Basic Structure
- One file which has the HTML "skeleton"
- One file with the custom React components written in JSX
- One script which generates all pages for the server to use
- One script to run the server
Results
After I generate the pages and run the server, I go to 127.0.0.1
and am presented with the header hydrate, a button, and two links. I can click the button, but nothing happens. After a few moments, the document finishes loading and the button starts counting my clicks. Then I click on the "render" link. Now, the page I'm presented with has the header render and two links, but no button. After a few moments, the button appears and is immediately responsive.
Explanation
On the "hydrate" page, all the markup is immediately rendered, because all the necessary html is served with the page. The button is unresponsive because there are no callbacks connected yet. Once components.js
finishes loading, the load
event fires from the window
and the callbacks are connected with hydrate
.
On the "render" page, the button markup isn't served with the page, but only injected by ReactDOM.render
, so it isn't immediately visible. Note how the appearance of the page is jarringly changed by the script finally loading.
Source
Here is the custom react component I am using. It will be used by the server in node with react to statically render components, and it will also be loaded dynamically from the server for use in pages (this is the purpose of checking for exports
and React
objects at the beginning of the file).
// components.jsx
var exports = typeof(exports) == 'object' ? exports : ;
var React = typeof(React) == 'object' ? React : require('react');
function MyButton(props)
[click, setClick] = React.useState(0);
function handleClick() setClick(click + 1);
return (
);
exports.MyButton = MyButton;
This is the script used to generate all the pages required for the server. First, babel is used to transpile components.jsx into javascript, then these components are used, along with React and ReactDOMServer, to create the actual pages. These pages are created with the fuction getPage
which is exported from the file pageTemplate.js
, shown next.
// genScript.js
let babel = require('@babel/core');
let fs = require('fs');
let ReactDOMServer = require('react-dom/server');
let React = require('react');
let pageTemplate = require('./pageTemplate.js');
script = babel.transformFileSync(
'components.jsx',
presets : [['@babel/react']]
);
fs.writeFileSync('components.js',script.code);
let components = require('./components.js');
hydrateHTML = pageTemplate.getPage(
'MyButton',
ReactDOMServer.renderToString(React.createElement(components.MyButton)),
'hydrate'
);
renderHTML = pageTemplate.getPage(
'MyButton',
'',
'render'
);
fs.writeFileSync('hydrate.html',hydrateHTML);
fs.writeFileSync('render.html',renderHTML);
This file just exports the getPage
function mentioned previously.
// pageTemplate.js
exports.getPage = function(
reactElementTag,
reactElementString,
reactDOMMethod
)
return `
$ reactDOMMethod
$ reactElementString
hidratar
hacer
`;
Finalmente, el servidor real
// server.js
let http = require('http');
let fs = require('fs');
let renderPage = fs.readFileSync('render.html');
let hydratePage = fs.readFileSync('hydrate.html');
let componentsSource = fs.readFileSync('components.js');
http.createServer((req, res) =>
if (req.url == '/components.js')
// artificial delay
setTimeout(() =>
res.setHeader('Content-Type','text/javascript');
res.end(componentsSource);
, 2000);
else if (req.url == '/render.html')
res.end(renderPage);
else
res.end(hydratePage);
).listen(80,'127.0.0.1');
Recuerda algo, que tienes la opción de decir si atinaste tu asunto justo a tiempo.