Skip to main content
🍞
Dev Corner
Decoding the Hype: What Are React Server Components?

Decoding the Hype: What Are React Server Components?

The announcement of React Server Components was a paradigm shift in the world of React. But what exactly is a React Server Component?

Decoding the Hype: What Are React Server Components?

And is it something you should use in your application? Does it replace SSR and suspense? Let’s go through each of these questions individually and better understand the core concepts behind React Server Components, their advantages, and their impact on modern web development practices.

What are React Server Components?

Before we go any further, I would like to make it clear that at the time of writing this post, React Server Components are an experimental feature and are not fully production-ready yet.

Alright, let’s get into it! As the name suggests, React Server Components (RSCs) are React components that run on the server. These components run exclusively on the server and are never shipped to the client.

Simply put, Imagine you're building a complex React application. The challenge is handling large amounts of data and ensuring a snappy user experience. This is where React Server Components come into play.

In a typical React setup, all the heavy lifting, including rendering components and fetching data, happens on the client side. React Server Components, however, bring a fresh approach by enabling you to distribute some of this workload to the server. Let’s take a look at an example:

async function Pokemon(props) {
  const { id } = props;
  const pokemon = await fetch(`https://pokeapi.co/api/v2/ability/${id}`);
  return (
    <div>
      <h1>{pokemon.name}</h1>
      /* Other Pokémon data */
    </div>
  );
}

Here, we fetch data for an API and pre-render it on the server. React then seamlessly streams the content to the client side, where it is hydrated.

In essence, React Server Components offer a powerful way to balance the workload between the server and the client, resulting in a faster, more efficient, and scalable React application. They shine in scenarios where optimizing for performance, especially in terms of rendering and data fetching, is a top priority.

React Server Components Key Features

Now that we know what a React Server Component is, there are some key features that you should be aware of as well:

  • Zero Bundle Size. Server Components do not add to the client-side bundle size. They are rendered on the server and send minimal, serialized UI to the client. Want to use a library but worried about the increase in the bundle size? With server components, you can avoid sending this to the client, resulting in no increase in the JavaScript bundle size.
  • Rich Data Fetching. They can directly access server-side data sources, eliminating the need for additional data-fetching layers on the client side.
  • Unified Development Model. Developers can seamlessly intermix client and server components, streamlining the development process.
  • No re-renders. RSCs do not re-render. They run once to generate the UI, and that’s it. As server components only run on the server, they do not reach the client at all. This is why you can not use state or effects with these components.
  • One of the cooler things about Server Components is the client state retention. When you make a change to a server component, such as manipulating data via it, the refetching of the tree does not cause the existing client state to reset. This results in a smoother user experience.

⚠️ Please note that re-rendering does happen when a user navigates around or reloads the page.

How Do React Server Components Work?

Let’s take a look at how exactly a Server Component is rendered.

  • Request Handling. The server determines which components are needed upon a user's request.
  • Server-side Execution. Server Components execute on the server, accessing databases or file systems if necessary.
  • Serialization. The output is serialized and sent to the client.
  • Hydration. The client (browser) then receives the serialized data and starts the work of constructing the React tree that will be rendered.

Advantages of React Server Components

Now we know how RSW works, let’s talk about the benefits of using them.

Enhanced Performance

As mentioned in the key features section, RSCs have a zero bundle size and, as such, are not included in JS bundles that are generated. This significantly improves application performance as the total amount of JS needed to be downloaded is way less.

Efficient Data Handling

Direct server access for data fetching streamlines data retrieval processes, reducing the need for complex client-side data management strategies.

Simplified Codebase

Developers can write in a more unified and natural style, blending server and client components without cumbersome distinctions.

Server Components vs. Client Components

We have been talking about server components a lot, but what are client components? Well, those are just our good ol’ React components that have been renamed. This is done to make distinguishing between server and client components easier.

While server components focus on server-side magic and clever revalidation, client components do the heavy lifting on the user's device. They handle dynamic interactions and manage the local state.

"use client" Directive:

The " use client " directive explicitly designates a component as a client component. By placing this directive at the top of a file, you signal to the bundler that the associated component is intended for execution on the client side.

"use client"
import React from 'react';
function EditPokemonName() {
  const [name, setName] = useState("");
  const handleNameChange = (newName) => {
	  //code
  };
  return (
    <div>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <button onClick={() => handleNameChange(name)}>
        Update Pokémon Name
      </button>
    </div>
  );
}
export default EditPokemon;

The component above is a client component, you can absolutely add client components in server components. Below, we add the EditPokemonName component to our server component.

async function Pokemon(props) {
  const { id } = props;
  const pokemon = await fetch(`https://pokeapi.co/api/v2/ability/${id}`);
  return (
    <div>
      <h1>{pokemon.name}</h1>
      <EditPokemonName/>
    </div>
  );
}

In conclusion, these two work as a team, resulting in a more seamless experience for the end user. One thing to note here is that you cannot next a server component in a client component. This might be a little confusing and take some time getting used to.

"use client" Directive:

React SSR vs. RSC: Clearing the Confusion

So, do RSCs replace SSR? No, they do not. We continue to depend on server-side rendering (SSR) to generate the initial HTML. React Server Components extends this capability by allowing the exclusion of specific components from the client-side JavaScript bundle, ensuring their execution solely on the server.

Interestingly, React Server Components can be utilized even without server-side rendering. However, in practice, employing them together yields superior results. As the React team has mentioned, these two complement each other. You can use the server component without using SSR and vice-versa.

Meta-Frameworks

To make the adoption more convenient, server components will initially be adopted via meta—frameworks such as Next.js. Currently, Next.js is the only framework that utilizes these. You can keep track of the frameworks in the React documentation.

Conclusion

React Server Components represent a significant leap in web development, offering a more efficient, performance-oriented approach to building web applications. As this technology evolves, it's poised to redefine modern web development's best practices and standards, emphasizing performance, simplicity, and a seamless developer experience.