Information Meeting and Replace Mechanism in SSR and Hydration
This text explains the workflow of server-side rendering (SSR) and client-side hydration in Subsequent.js. It covers the method of server-side knowledge injection, client-side hydration, and mechanisms to make sure well timed updates to knowledge (e.g., self.__next_f
). Moreover, we talk about dealing with situations the place web page.js
is loaded earlier than the information.
1. Workflow of Server-Facet Rendering (SSR)
a) Server Obtains Information
In SSR frameworks like Subsequent.js, knowledge required by the web page is fetched server-side, sometimes utilizing getServerSideProps
or getStaticProps
.
Instance:
1 export async operate getServerSideProps() {
2 const res = await fetch('https://api.instance.com/knowledge');
3 const knowledge = await res.json();
4 return { props: { knowledge } };
5 }
b) Injecting Information into HTML
As soon as knowledge is fetched, it’s injected into the HTML, generally utilizing:
- Script tags: Serialize the information into JSON and embed it.
- World variables: Assign knowledge to international variables like
self.__next_f
.
c) Ship HTML to the Consumer
The HTML, containing the information, is distributed to the consumer.
d) Consumer Hydration
On the consumer aspect, React and the web page JavaScript extract knowledge injected by the server and “activate” the static HTML utilizing ReactDOM.hydrate
.
2. Implementation Particulars
a) Server-Facet Information Injection
Information is serialized into JSON and embedded in an HTML <script>
tag.
Instance:
1 import ReactDOMServer from 'react-dom/server';
2
3 operate App({ knowledge }) {
4 return <div>{knowledge.message}</div>;
5 }
6
7 export async operate getServerSideProps() {
8 const knowledge = { message: 'Whats up, world!' };
9 return { props: { knowledge } };
10 }
11
12 export operate renderToStringWithData(App, props) {
13 const html = ReactDOMServer.renderToString(<App {...props} />);
14 const dataScript = `<script>self.__next_f = ${JSON.stringify(props)};</script>`;
15 return `
16 <!DOCTYPE html>
17 <html>
18 <head><title>SSR Instance</title></head>
19 <physique>
20 <div id="root">${html}</div>
21 ${dataScript}
22 <script src="/consumer.js"></script>
23 </physique>
24 </html>
25 `;
26 }
b) Consumer Hydration
The consumer extracts knowledge from self.__next_f
and prompts the web page.
Instance:
1 import React from 'react';
2 import ReactDOM from 'react-dom';
3 import App from './App';
4
5 const knowledge = self.__next_f;
6 ReactDOM.hydrate(<App {...knowledge} />, doc.getElementById('root'));
3. Guaranteeing Well timed Updates to self.__next_f
a) Utilizing Proxy to Monitor Modifications
A Proxy
object can observe modifications to self.__next_f
and set off hydration when knowledge updates.
Instance:
1 self.__next_f = self.__next_f || [];
2
3 self.__next_f = new Proxy(self.__next_f, {
4 set(goal, prop, worth) {
5 const end result = Replicate.set(goal, prop, worth);
6 if (prop === 'size' && worth > 0) {
7 console.log('Information up to date:', goal);
8 hydrateApp(goal);
9 }
10 return end result;
11 }
12 });
13
14 operate hydrateApp(knowledge) {
15 const parsedData = JSON.parse(knowledge[0][1]);
16 ReactDOM.hydrate(<App knowledge={parsedData} />, doc.getElementById('root'));
17 }
b) Monitoring Information in web page.js
The script waits for knowledge availability earlier than continuing.
Instance:
1 operate waitForData() {
2 return new Promise((resolve) => {
3 if (self.__next_f && self.__next_f.size > 0) {
4 resolve();
5 } else {
6 const observer = new MutationObserver(() => {
7 if (self.__next_f && self.__next_f.size > 0) {
8 observer.disconnect();
9 resolve();
10 }
11 });
12 observer.observe(doc.physique, { childList: true, subtree: true });
13 }
14 });
15 }
16
17 waitForData().then(() => {
18 const knowledge = JSON.parse(self.__next_f[0][1]);
19 ReactDOM.hydrate(<App knowledge={knowledge} />, doc.getElementById('root'));
20 });
4. Dealing with web page.js
Loading Earlier than Information
a) Initialize self.__next_f
Add an initialization script within the HTML header:
1 <script>
2 self.__next_f = self.__next_f || [];
3 </script>
b) Embed Information Submit-HTML
Embed knowledge after the HTML:
1 <script>
2 self.__next_f.push([1, "{"name":"The Octocat"}"]);
3 </script>
Conclusion
By implementing these methods, you’ll be able to:
- Guarantee server-side knowledge is appropriately injected into HTML.
- Facilitate well timed client-side hydration.
- Deal with circumstances the place
web page.js
masses earlier than knowledge.
These practices improve the reliability and effectivity of SSR and hydration in Subsequent.js.