मेरे पास इसके उपयोग के बारे में जो कुछ भी कहा गया है उसे जोड़ने के लिए कुछ भी विशिष्ट नहीं है hydrate
, लेकिन इसके बारे में जानने की कोशिश में मैंने एक छोटा सा उदाहरण एक साथ रखा है, इसलिए यहां जो भी इसके लिए उपयोगी है वह काम है।
लक्ष्य
दो पृष्ठों की सेवा करें, एक जो उपयोग करता है ReactDOM.hydrate
और एक जो उपयोग करता है ReactDOM.render
। वे पर कुछ JSX में लिखा घटक है, जो द्वारा लोड किए गए हैं प्रतिक्रिया निर्भर करेगा <script>
टैग, के बीच अंतर दर्शाने के लिए कृत्रिम देरी (सर्वर) के द्वारा दिए गए hydrate
और render
।
बुनियादी संरचना
- एक फ़ाइल जिसमें HTML "कंकाल" है
- JSX में लिखे गए कस्टम रिएक्ट घटकों के साथ एक फ़ाइल
- एक स्क्रिप्ट जो सर्वर के सभी पेजों को इस्तेमाल करने के लिए तैयार करती है
- सर्वर को चलाने के लिए एक स्क्रिप्ट
परिणाम
मैं पेज जेनरेट करने और सर्वर चलाने के बाद, मैं 127.0.0.1
हेडर हाइड्रेट , एक बटन और दो लिंक के साथ प्रस्तुत किया जाता हूं । मैं बटन पर क्लिक कर सकता हूं, लेकिन ऐसा कुछ नहीं होता है। कुछ क्षणों के बाद, दस्तावेज़ लोड करना समाप्त कर देता है और बटन मेरे क्लिकों को गिनना शुरू कर देता है। फिर मैं "रेंडर" लिंक पर क्लिक करता हूं। अब, मैं जिस पृष्ठ के साथ प्रस्तुत किया गया है उसमें हेडर रेंडर और दो लिंक हैं, लेकिन कोई बटन नहीं है। कुछ क्षणों के बाद, बटन दिखाई देता है और तुरंत उत्तरदायी होता है।
व्याख्या
"हाइड्रेट" पृष्ठ पर, सभी मार्कअप को तुरंत प्रदान किया जाता है, क्योंकि सभी आवश्यक HTML को पृष्ठ के साथ परोसा जाता है। बटन अनुत्तरदायी है क्योंकि अभी तक कोई कॉलबैक जुड़ा नहीं है। एक बार components.js
लोडिंग खत्म होने पर, load
ईवेंट कॉल window
और कॉलबैक से कनेक्ट हो जाता है hydrate
।
"रेंडर" पृष्ठ पर, बटन मार्कअप पृष्ठ के साथ नहीं दिया जाता है, लेकिन केवल इसके द्वारा इंजेक्ट किया जाता है ReactDOM.render
, इसलिए यह तुरंत दिखाई नहीं देता है। ध्यान दें कि स्क्रिप्ट के अंत में पृष्ठ का स्वरूप किस तरह से बदल जाता है।
स्रोत
यहाँ कस्टम प्रतिक्रिया घटक है जिसका मैं उपयोग कर रहा हूँ। इसे सर्वर द्वारा नोड में सांख्यिकीय रूप से रेंडर घटकों पर प्रतिक्रिया के साथ उपयोग किया जाएगा, और इसे पृष्ठों में उपयोग के लिए सर्वर से गतिशील रूप से लोड किया जाएगा (यह फ़ाइल की शुरुआत में वस्तुओं exports
और React
वस्तुओं की जांच का उद्देश्य है )।
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 (
<button onClick={handleClick}>Clicked: {click}</button>
);
}
exports.MyButton = MyButton;
यह वह स्क्रिप्ट है जिसका उपयोग सर्वर के लिए आवश्यक सभी पृष्ठों को उत्पन्न करने के लिए किया जाता है। सबसे पहले, babel का उपयोग जावास्क्रिप्ट में ट्रांसपाइल घटकों.jsx में किया जाता है, फिर इन घटकों का उपयोग वास्तविक पेज बनाने के लिए React और ReactDOMServer के साथ किया जाता है। ये पृष्ठ उस फ़िशन के साथ बनाए जाते हैं , getPage
जिसे फ़ाइल से निर्यात किया जाता है pageTemplate.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);
यह फ़ाइल getPage
पहले बताए गए फंक्शन को एक्सपोर्ट करती है ।
exports.getPage = function(
reactElementTag,
reactElementString,
reactDOMMethod
) {
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js" defer></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" defer></script>
<script src="./components.js" defer></script>
</head>
<body>
<h1>${ reactDOMMethod }</h1>
<div id="react-root">${ reactElementString }</div>
<a href="hydrate.html">hydrate</a>
<a href="render.html">render</a>
</body>
<script>
window.addEventListener('load', (e) => {
ReactDOM.${ reactDOMMethod }(
React.createElement(${ reactElementTag }),
document.getElementById('react-root')
);
});
</script>
</html>
`;
}
अंत में, वास्तविक सर्वर
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') {
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');