โ€” ยท 5 min read

Unraveling React Server Components

React has revolutionized the way we think about web development, with its component-based architecture and its simplified approach to state management. As a leader in the field, React's development team has continually pushed the boundaries of what's possible in the realm of user interfaces, and their latest innovation, React Server Components, is no exception.

React Server Components (RSC) represents a significant evolution in React's model. By allowing developers to build components that run only on the server, React is changing the way we conceive of and build React applications. This blog post aims to explain what React Server Components are, how they work, and the potential benefits they bring.

What Are React Server Components?

React Server Components are a new type of component that can be rendered only on the server and sent to the client as HTML. Unlike traditional React components, they do not run any JavaScript on the client, which means they are more performant and consume less bandwidth.

This is a major departure from the typical React model where components are bundled, downloaded, and run in the client's browser. Instead, RSC allows for components to run server-side, where they can take advantage of direct access to databases or file systems without the need for API calls. After processing, the results are sent as HTML to the client.

How Do React Server Components Work?

React Server Components are written in a .server.ts (or .server.js for JavaScript) file. When these server components are requested by the client, they're rendered on the server, and HTML is sent back to the client. Importantly, these components maintain the interactivity of standard React components by leveraging client components where necessary.

Server components can be mixed with client components, allowing developers to decide where their logic should run based on the needs of their application. The distinction between the two is that server components do not have side effects on the client side, do not use React hooks, and they don't directly handle user events like clicks or input.

When you change the state that a server component depends on, React re-renders that component and its sub-tree on the server and sends the new HTML to the client. One of the main advantages here is that the client doesn't have to do any heavy lifting.

React rendering tree

React Server Components in Action: A TypeScript Example

Let's illustrate with a simple TypeScript example. Let's say we're building a blog site and we want to render a list of blog post titles on our page.

First, we'll write a server component that fetches the list of blog post titles from our database. The file would be named Blog.server.tsx following the naming convention for server components (*.server.ts).

Blog.server.tsx
import { db } from "./db";
 
type BlogPost = {
  id: string;
  title: string;
};
 
export default function Blog() {
  // Fetch blog post titles directly from the database (and await it!)
  const blogPosts: BlogPost[] = await db.query("SELECT title FROM blog_posts");
 
  // Return the list of blog post titles
  return (
    <ul>
      {blogPosts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

Now, let's write a client component that uses our Blog server component. This client component could be named Home.tsx.

HomePage.tsx
import React from "react";
import Blog from "./Blog.server";
 
export default function Home() {
  return (
    <div>
      <h1>Welcome to our blog!</h1>
      <Blog />
    </div>
  );
}

In this example, Blog.server.tsx runs on the server and directly fetches data from our database. It then renders HTML which is sent to the client. On the client side, the Home.tsx component includes the server component BlogPostList just like it would with a regular React component.

Advantages of React Server Components

Improved Performance

Since server components don't run JavaScript in the browser, they are significantly more performant. They don't impact the client-side bundle size, leading to faster load times and better performance on slower networks or less powerful devices.

Reduced Client-side Complexity

Server components can directly access back-end services or databases, eliminating the need for a lot of client-side logic and fetching. This can simplify the structure of your application and make it easier to manage and debug. Also: awaiting promises inside our component is pretty amazing.

Richer User Experiences

By offloading tasks to the server, you can create more complex interfaces without slowing down the client. This can lead to more engaging user experiences, without sacrificing performance.

The Future with React Server Components

React Server Components offers a new paradigm for building web applications, combining the best of server-side and client-side rendering. They promise to bring about a new era of more performant and user-friendly web applications.

However, it's important to note that as of this writing, React Server Components are still experimental. They're a glimpse into the future of what's possible with React, but are not yet recommended for use in production environments.

React Server Components are an exciting development and represent a significant advancement in how we can build and optimize web applications. They're a testament to React's ongoing innovation and commitment to making web development easier, more flexible, and more powerful. Keep an eye on the evolution of React Server Components; they're set to be a game-changer!