How RCS Works Underneath the Hood? - P.2

A really Deep Dive 🤿

·

4 min read

How RCS Works Underneath the Hood? - P.2

Welcome back, folks.

In this article, let’s look deeply at how React Server Component works behind the scenes.

Let’s say we have an app that uses the RSC Architecture, and we have a tree look like this, a mix of both Client Component Instances (CC) and Server Component Instances (SC) - for short.

In reality, the terms Component Instances and Component can be used interchangeably.

I wrote an entire article on React Component, Instances, and Element. Make sure you check it our HERE.

HOW and WHERE are Client and Server Component Instances rendered?

1️⃣ SERVER COMPONENTS 🤖

When React encountered the tree like this, all the SCs of course, rendered on the SERVER.

👉 Render a component, resulting in a React Element.

👉 Each of these React Elements just contains the output of the Server Component, to be more specific, only the information on HOW the DOM for each component will LOOK LIKE.

They no longer contain the code necessary to render each component.

🦖 The code from the SC has disappeared RIGHT on the SERVER

🙋 BUT wait? WHY does it matter? 🤯

❌ THIS is the technical reason why we CAN’T USE STATE in server components.

👉 Because functions like useState , useEffect,… these will disappear as components are rendered.

👉 It has to be this way, because these React elements on the server will be sent to CLIENT later.

The whole things need to be serializable while functions and classes are not. As we just discussed before in the previous article.

👉 There is NO WAY to send functions like useState, useEffect,… to the browser.

👉 There is also NO WAY to keeping track of State, cause there’s also NO FIBER tree on the server.

👉 Even when we have Fiber tree on the server, we cannot send the whole data structure to the client anyway.

2️⃣ CLIENT COMPONENTS 🐥

Since we’re still on the server.

This is NOT the environment for Client components to be rendered.

Instead,

The component tree on the Server contains a “hole” aka Placeholder for future Client components that will eventually rendered.

Each of the CC “Hole” will contain

  • Serialized props passed from SC to CC 🔽

  • ✉️ URL to script references the code necessary so that the client component can later be executed on the client. - the complex process must be powered by the framework’s bundler. Not by React itself.

At the end of this step, we have a weird tree that is a mix of executed and unexecuted component instances.

✅ It’s a so-called RSC PAYLOAD.

  • Is a Virtual DOM of all Server Components, since these have already been rendered AND some subtree of un-rendered Client Component.

  • This is called RSC PAYLOAD because, this data structure will then be sent to the CLIENT in the next step.

When this RSC payload eventually reached the Client.

It’s when the client components are finally rendered as well. Also, resulted in new React element.

🎉 With all of this, we now have a completed, final VIRTUAL DOM on the CLIENT, ready to commit to the DOM.

🤜 Caveat: The terms CLIENT and SERVER here don’t mean in the typical sense of “web server” and “client” browser. Just in term of React itself, split into 2 different environments.

Why we need RSC payload?

Why not render SCs directly as HTML, and send to client? 😾

This is because

  • React want to describes the UI as data, not as finished HTML. This is why state, and fiber exist in the first place.

  • When a SC is re-rendered, React is able to merge - Reconcile the current tree on the client with a new tree coming from the server. Normal HTML doesn’t have concept of “state”, all the state will be lost.

  • As a result, UI state can be preserved when a SC re-renders, instead of completely regenerating the entire page as HTML.

More Observations

  • All the steps during the rendering process don’t wait for one another to finish. Instead, completed works on the server is STREAMED to the client right away, and seamlessly integrated into the client tree overtime.

  • The statement of SSR UI = f(data, state) is not 100% correct based on what we learned here

  • BUT it’s something like this UI = f(data) (state) first UI is the function of data , THEN, state is the input for the function that is returned from FIRST step

That’s it for this article.

Thanks for reading till the end.

I hope you enjoy.

See you in the next one soon. Where we’ll discuss about how are SSR and RSC related?

Stay tuned and take care.

_

Reference source: Jonas Schmedtmann