React Server Component, What It is?
My recap learning what are React Server Component, and why this will be a game-changer from React.
In the last year of 2020 almost 2 years back, React core team has been announced about React Server Component (RSC) indeed at that time, it was not compatible with React yet, but until now (2022) this method has been adopted on the Next.JS framework (Just this framework as far as I know).
I will not try to give an example of the implementation on Next.JS itself, but I will try to explain the basic knowledge about RSC, at a glance in the terms of the name we can imagine that our React component will run under SSR (Server Side Rendering) — this was explained detail by React core team in here.
Again, at a glance, this is an alike way that we render our component on a server and we send it to the client through the renderToString
from react-dom
API and the result will give to the user in an HTML format that the user just renders on the browser, but this is (RSC) slightly different from SSR, let’s see the example of RSC result on the network browser below:
According to the image above, seems like RSC will respond to the client in something not like an HTML format instead, which looks like an object that React will try to handle that stuff and magically will render to the browser with proper UI.
Keep in mind, because the name is React Server Component — which contains the word “Component” that we already know within the component we can use useState
or other API from React to make our component re-render or use any side-effect to call a DOM.
In this RSC we cannot do that on the server, like usual we render our component on the server, we just served it to the browser in the first time of render in the browser, according to the React core team RSC will help us to solve a bundle-size problem also will help on the performance things.
There is an interesting part of this RSC we can use 3 types of files that we can use it:
- .server.js
- .client.js
- .js (Shared)
I will try to explain the difference between each of the above files.
.client.js
The new extension name front .js
which is .client.js
the file will not make us satisfied, because we already mostly use that such as to make our component re-render or make interaction with DOM and etc.
In this file, we also cannot call or import from .server.js
(I will try to explain it below) but we could smoothly get data that was already constructed from the server and pass it to this file.
.server.js
Basically, we can call any server call in this file such as get data from the Database or read a file and etc. Let’s try to see this example of code below:
// Note.server.js
import db from "db.server";
function Note(props) {
const { id, isEditing } = props;
const note = db.posts.get(id); // let's say this is a process to get a data from Database
return (
<div>
<h1>{note.title}</h1>
<section>{note.body}</section>
</div>
);
}
As you can see, we call a DB directly — in fact, we also make a result of that component with zero-bundle size which means that I already told you before, React core team will solve a bundle size problem through RSC, let’s take a look this example code below:
// NoteWithMarkdown.js
import marked from 'marked'; // 35.9K (11.2K gzipped)
import sanitizeHtml from 'sanitize-html'; // 206K (63.3K gzipped)
function NoteWithMarkdown({text}) {
const html = sanitizeHtml(marked(text));
return (/* render */);
}
Let’s say, the above code with the name NoteWithMarkdown.js
before (RSC) now we talk about it, mostly our component will import some third-party library out there isn’t it?
That will make a user download more size of JS files on their network which effected to the user, this means a user will take much time to download or wait for our component basically, there will leave this is bad from the UX perspective.
But, let's say the above code we change it with RSC terms, we change it with NoteWithMarkdown.server.js
take a look an example code below:
// NoteWithMarkdown.server.js
import marked from 'marked'; // 0K atau zero-bundle size
import sanitizeHtml from 'sanitize-html'; // 0K atau zero-bundle size
function NoteWithMarkdown({text}) {
const html = sanitizeHtml(marked(text));
return (/* render */);
}
As you can see, this will make that component as zero-bundle size component because we smoothly put it that process on the server and just give to the client with no additional JS file size.
The good thing with this file extension we can call a client file which is .client.js
(not like a client that we cannot import it). If you are familiar with Next.JS this process maybe slightly same, let’s take an example below code:
// NoteWithMarkdown.server.js
import marked from "marked"; // 0K atau zero-bundle size
import sanitizeHtml from "sanitize-html"; // 0K atau zero-bundle size
import NoteEditor from "./NoteEditor.client";
function NoteWithMarkdown({ text }) {
const html = sanitizeHtml(marked(text));
return <NoteEditor html={html} />;
}
What does the above code mean? does the user will not download the .client.js
file too? — the answer is No, because after the user executes it on the server they will still need to download .client.js
because we already mark that file ends with .client.js
that’s it.
.js (Shared)
This file extension just like a normal component that we already use it day-by-day, but after the RSC comes to the production this component will automatically call as .server.js
file.
Conclusion
This will help us to make sure there’s no more additional file size on the client that the user will need to more extra to download it. This also comes with the downside which means it will cost more extra on the server which means we need to make sure our infrastructure it’s enough to use this RSC.
Also as far as I know (at the time of this writing) it’s still not yet full supported to the production, but the framework that already use it is Next.JS you can check this documentation.