React Server Component, What It’s?
My recap learning what are React Server Component, and why this will be a game-changer from React.
Table of contents
In the last year of 2020 almost 2 years back, the React core team 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 a similar way that we render our component on a server and send it to the client through the renderToString
from react-dom
API and the result will be given 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 serve it to the browser the first time of rendered 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 interaction with DOM, 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 that, 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 affects the user, this means a user will take much time to download or wait for our component basically, this will leave this 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 at 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 that process on the server and just give it 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 the 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 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
it because we already mark that file ending with .client.js
that’s it.
.js (Shared)
This file extension is just like a normal component that we already use day-by-day, but after the RSC comes to 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 do extra to download it. This also comes with the downside which means it will cost more on the server which means we need to make sure our infrastructure is enough to use this RSC.
Also as far as I know (at the time of this writing) it’s still not yet fully supported for production, but the framework that already uses it is Next.JS you can check this documentation.