रिएक्ट 16 में हाइड्रेट () और रेंडर () के बीच क्या अंतर है?


86

मैंने प्रलेखन पढ़ा है, लेकिन मैं वास्तव में hydrate()और render()प्रतिक्रिया 16 के बीच के अंतर को नहीं समझ पाया ।

मुझे पता hydrate()है कि SSR और क्लाइंट-साइड रेंडरिंग को संयोजित करने के लिए उपयोग किया जाता है।

क्या कोई समझा सकता है कि हाइड्रेटिंग क्या है और फिर ReactDOM में क्या अंतर है?


नीचे @tophar द्वारा दिए गए जवाब सही है, अगर आप अधिक यह पता लगाने के लिए चाहते हैं आप इसे पढ़ सकते reactjs.org/docs/react-dom.html
गोरख नाथ

जवाबों:


80

से ReactDOMServer डॉक्स (जोर मेरा):

यदि आप ReactDOM.hydrate()उस नोड पर कॉल करते हैं जिसमें पहले से ही यह सर्वर-आधारित मार्कअप है, तो रिएक्ट इसे संरक्षित करेगा और केवल ईवेंट हैंडलर संलग्न करेगा , जिससे आपको एक बहुत अच्छा प्रदर्शन करने वाला पहला-लोड अनुभव होगा।

बोल्ड में पाठ मुख्य अंतर है। renderयदि आरंभिक DOM और वर्तमान DOM के बीच अंतर है, तो अपना नोड बदल सकते हैं। hydrateकेवल ईवेंट हैंडलर संलग्न करेंगे।

एक अलग API के रूप में पेश किएhydrate गए Github मुद्दे से :

यदि यह आपका प्रारंभिक DOM है:

<div id="container">
    <div class="spinner">Loading...</div>
</div>

और फिर कॉल करें:

ReactDOM.render(
   <div class="myapp">
      <span>App</span>
   </div>,
   document.getElementById('container')
)

केवल क्लाइंट-साइड रेंडर (हाइड्रेशन नहीं) करने का इरादा है। फिर आप के साथ समाप्त होता है

<div id="container">
   <div class="spinner">
       <span>App</span>
   </div>
</div>

क्योंकि हम विशेषताओं को पैच नहीं करते हैं।

सिर्फ FYI कारण है कि वे विशेषताओं पैच नहीं था

... यह वास्तव में सामान्य हाइड्रेशन मोड में हाइड्रेट करने के लिए धीमा होगा और एक गैर-एसएसआर पेड़ में प्रारंभिक रेंडर को धीमा कर देगा।


8
मुझे समझ में नहीं आता है कि रेंडर किए गए डिव नॉट ने डिवोर्स के साथ क्लासेस का नाम myapp क्यों रखा है और फाइनल रेंडर एलिमेंट में स्पिनर क्लास क्यों है
प्रवीण पौडेल

2
@pravinpoudel मुझे लगता है कि यह है क्योंकि वे क्लाइंट-साइड रेंडरिंग के दौरान विशेषताओं को पैच नहीं करते हैं। इसीलिए गुण तत्व class="spinner"में जैसा है वैसा ही रहता है <div>
ग्लेन मोहम्मद

31

हाइड्रेट मूल रूप से SSR (सर्वर साइड रेंडरिंग) के मामले में उपयोग किया जाता है। SSR आपको कंकाल या HTML मार्कअप देता है, जो सर्वर से शिप किया जा रहा है ताकि पहली बार जब आपका पेज लोड हो जाए तो यह खाली न हो और सर्च इंजन बॉट्स इसे SEO (SSR का उपयोग केस) के लिए इंडेक्स कर सके। इसलिए हाइड्रेट आपके पेज या SSR को लागू करने वाले नोड को JS जोड़ता है। ताकि आपका पृष्ठ उपयोगकर्ता द्वारा की गई घटनाओं पर प्रतिक्रिया दे सके।

रेंडर का उपयोग क्लाइंट साइड ब्राउज़र प्लस पर कंपोनेंट को रेंडर करने के लिए किया जाता है यदि आप हाइड्रेट को रेंडर से बदलने की कोशिश करते हैं तो आपको एक चेतावनी मिलेगी कि रेंडर अपग्रेड किया गया है और एसएसआर के मामले में उपयोग नहीं किया जा सकता है। हाइड्रेट की तुलना में धीमी होने के कारण इसे हटा दिया गया था।


23

मेरे पास इसके उपयोग के बारे में जो कुछ भी कहा गया है उसे जोड़ने के लिए कुछ भी विशिष्ट नहीं है hydrate, लेकिन इसके बारे में जानने की कोशिश में मैंने एक छोटा सा उदाहरण एक साथ रखा है, इसलिए यहां जो भी इसके लिए उपयोगी है वह काम है।

लक्ष्य

दो पृष्ठों की सेवा करें, एक जो उपयोग करता है ReactDOM.hydrateऔर एक जो उपयोग करता है ReactDOM.render। वे पर कुछ JSX में लिखा घटक है, जो द्वारा लोड किए गए हैं प्रतिक्रिया निर्भर करेगा <script>टैग, के बीच अंतर दर्शाने के लिए कृत्रिम देरी (सर्वर) के द्वारा दिए गए hydrateऔर render

बुनियादी संरचना

  1. एक फ़ाइल जिसमें HTML "कंकाल" है
  2. JSX में लिखे गए कस्टम रिएक्ट घटकों के साथ एक फ़ाइल
  3. एक स्क्रिप्ट जो सर्वर के सभी पेजों को इस्तेमाल करने के लिए तैयार करती है
  4. सर्वर को चलाने के लिए एक स्क्रिप्ट

परिणाम

मैं पेज जेनरेट करने और सर्वर चलाने के बाद, मैं 127.0.0.1हेडर हाइड्रेट , एक बटन और दो लिंक के साथ प्रस्तुत किया जाता हूं । मैं बटन पर क्लिक कर सकता हूं, लेकिन ऐसा कुछ नहीं होता है। कुछ क्षणों के बाद, दस्तावेज़ लोड करना समाप्त कर देता है और बटन मेरे क्लिकों को गिनना शुरू कर देता है। फिर मैं "रेंडर" लिंक पर क्लिक करता हूं। अब, मैं जिस पृष्ठ के साथ प्रस्तुत किया गया है उसमें हेडर रेंडर और दो लिंक हैं, लेकिन कोई बटन नहीं है। कुछ क्षणों के बाद, बटन दिखाई देता है और तुरंत उत्तरदायी होता है।

व्याख्या

"हाइड्रेट" पृष्ठ पर, सभी मार्कअप को तुरंत प्रदान किया जाता है, क्योंकि सभी आवश्यक HTML को पृष्ठ के साथ परोसा जाता है। बटन अनुत्तरदायी है क्योंकि अभी तक कोई कॉलबैक जुड़ा नहीं है। एक बार components.jsलोडिंग खत्म होने पर, loadईवेंट कॉल windowऔर कॉलबैक से कनेक्ट हो जाता है hydrate

"रेंडर" पृष्ठ पर, बटन मार्कअप पृष्ठ के साथ नहीं दिया जाता है, लेकिन केवल इसके द्वारा इंजेक्ट किया जाता है ReactDOM.render, इसलिए यह तुरंत दिखाई नहीं देता है। ध्यान दें कि स्क्रिप्ट के अंत में पृष्ठ का स्वरूप किस तरह से बदल जाता है।

स्रोत

यहाँ कस्टम प्रतिक्रिया घटक है जिसका मैं उपयोग कर रहा हूँ। इसे सर्वर द्वारा नोड में सांख्यिकीय रूप से रेंडर घटकों पर प्रतिक्रिया के साथ उपयोग किया जाएगा, और इसे पृष्ठों में उपयोग के लिए सर्वर से गतिशील रूप से लोड किया जाएगा (यह फ़ाइल की शुरुआत में वस्तुओं exportsऔर Reactवस्तुओं की जांच का उद्देश्य है )।

// 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 (
    <button onClick={handleClick}>Clicked: {click}</button>
  );
}

exports.MyButton = MyButton;

यह वह स्क्रिप्ट है जिसका उपयोग सर्वर के लिए आवश्यक सभी पृष्ठों को उत्पन्न करने के लिए किया जाता है। सबसे पहले, babel का उपयोग जावास्क्रिप्ट में ट्रांसपाइल घटकों.jsx में किया जाता है, फिर इन घटकों का उपयोग वास्तविक पेज बनाने के लिए React और ReactDOMServer के साथ किया जाता है। ये पृष्ठ उस फ़िशन के साथ बनाए जाते हैं , getPageजिसे फ़ाइल से निर्यात किया जाता है pageTemplate.js, जो आगे दिखाया गया है।

// 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);

यह फ़ाइल getPageपहले बताए गए फंक्शन को एक्सपोर्ट करती है ।

// pageTemplate.js

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>
  `;
}

अंत में, वास्तविक सर्वर

// 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');

2
वाह। आपने मूल रूप से इस सवाल का जवाब दिया + बताया कि कैसे गैट्सबी जैसे न्यूनतम स्थिर जनरेटर का निर्माण किया जाए। गजब का। आपका बहुत बहुत धन्यवाद!
सर्गेई ल्यूकिन

22

उपरोक्त के अलावा ...

ReactDOM.hydrate()के रूप में ही है render(), लेकिन यह (एक घटना श्रोताओं को संलग्न) हाइड्रेट करने के लिए प्रयोग किया जाता है जिसका HTML सामग्री ReactDOMServer द्वारा प्रदान की गई थी। रिएक्ट इवेंट श्रोताओं को मौजूदा मार्कअप से जोड़ने का प्रयास करेगा

ReactDOM.render () का उपयोग सर्वर-रेंडर किए गए कंटेनर को हाइड्रेट करने के लिए किया जाता है क्योंकि धीमेपन के कारण इसे हटा दिया जाता है और रिएक्ट 17 में हटा दिया जाएगा इसलिए hydrate()इसके बजाय उपयोग करें ।


18

HTML में कार्यक्षमता डालने की पूरी प्रक्रिया जो पहले से ही सर्वर साइड रिएक्ट में दी गई थी, हाइड्रेशन कहलाती है।

इसलिए एक बार प्रदान किए गए HTML पर पुन: प्रतिपादन की प्रक्रिया को जलयोजन कहा जाता है।

तो अगर हम कॉल करके अपना काम पूरा करने की कोशिश करते हैं, तो हमें कॉल ReactDOM.render()करने की जरूरत है ReactDOM.hydrate()


1

रेंडर निर्दिष्ट तत्व में कुछ भी बाहर निकाल देगा (ज्यादातर मामलों में 'रूट' के रूप में नामित) और इसका पुनर्निर्माण करेगा, जबकि हाइड्रेट कुछ भी रखेगा जो पहले से ही निर्दिष्ट तत्व के अंदर है और इससे निर्माण होता है, जिससे प्रारंभिक पृष्ठ लोड तेजी से होता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.