Server Components: React.js and Next.js
What are Server Components?
RSC - React Server Components is an architecture model developed by the React team, this concept was introduced in December 2020 but this is nothing new, other programming languages like PHP, Python, Ruby and others already had content rendered on the server side, in summary, this is the main goal, to be able to render components on the server. There is a layer that pre-renders a large blob of static HTML content to avoid unnecessary usage of Javascript which is achieved by caching what needs to be rendered in the server. This happens using React Streaming which can be implemented using the new method renderToPipeableStream and React Suspense.
What benefits do they bring?
In React applications, Server Components exclude your Javascript from the bundle which allows us to fetch static content during the build and also read data without having to build the API, this scenario favours users with slower devices or network connections. React introduced async / await as the main way to fetch data from the server discarding the need to use the hook useEffect( ) for example, check the code below to see a request being made to the still using the hook useEffect( ) to fetch data from the API jsonplaceholder.typicode.com:
'use client'
import React, { useEffect, useState } from 'react';
export default function Home() {
const [data, setData] = useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts/')
.then((response) => response.json())
.then((data) => {
setData(data);
})
}, []);
return (
<div>
{data.map(post => (
<div>
<h1>{post.title}</h1>
<p>{post.body}</p>
</div>
))}
</div>
);
}
In the case of a Next.js application, all components are server components by default, if we wish to turn a specific component into a client component we have to use the flag ‘use client’ at the top to indicate that it is a server component and also a client component and with the ‘use client’ directive we can use hooks in the component.
export default async function Home() {
const response = await fetch('https://jsonplaceholder.typicode.com/posts')
const posts = await response.json();
return (
<>
<ul>
{posts.map(post => (
<div>
<h1>{post.title}</h1>
<p>{post.body}</p>
</div>
))}
</ul>
</>
)
}
Both codes displayed above will return the same content, a bunch of posts fetched from the API jsonplaceholder.typicode.com, but in the second example we have less lines of code and a code easier to read and grasp.
React server components help improve the performance of applications with code splitting, with lazy loading that hydrates only what is needed and it results in a bundle size being zero size and the SEO is great due to the fast loading of the page.
What are the downsides?
The server-only rendering on the server side is another environment and we will need to be more cautious about hydrations, what renders on the server must match what is hydrated on the client, if the content doesn't match then it will result in hydration errors.
Another hassle is that the server and infrastructure will be doing more work
Conclusion
Seeing that we have faster page loading, SEO, bundle size reduced, Code splitting, Streaming, Lazy loading, Suspense and other benefits, it's fairly recommended to use server components throughout our applications, and knowing when to use them is key to having better applications always aiming to provide our clients with the best experience they can get.
References
https://nextjs.org/docs/pages/building-your-application/rendering/server-side-rendering
Subscribe to my newsletter
Read articles from Hugo Ramon Pereira directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Hugo Ramon Pereira
Hugo Ramon Pereira
Frontend Developer with experience in building modern interfaces, providing the user with great experience, accessibility and responsiveness.