What the hell are React Server Components ?
Tags: react, javascript, rsc, nextjs
Published: 2022-12-25 20:05:00

## Introduction

React Server Components run _only_ on the server. The "only" part is important here. They are designed to leverage your servers better, as described in this [rfc](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md#rfc-react-server-components) published back around October 2022. You can think of them as Normal React Components, but that they only gets executed on server, and then they are sent to the client.

Normal React Components (when Server Rendered) are first "rendered" on the server into HTML and sent to the client (browser). Later, React adds interactivity to them (attaching event listeners to DOM elements). This process is called [Hydration](https://beta.reactjs.org/apis/react-dom/hydrate#hydrating-server-rendered-html)

In case of React Server Components, the execution process happens at the server. So, you can think like "hydration" of React Server Components happen only in the Server, the components get rendered into HTML and are sent to the client. And since, they are executed on the server, there is no need for Hydration on the client, and hence they ship [without increasing your bundle side](https://beta.nextjs.org/docs/rendering/server-and-client-components#why-server-components)

Here is a very good visual representation for you to understand the difference between Server Side Rendering and React Server Components (Credit: [@shuding\_](https://twitter.com/shuding_/status/1603525151492022273)):

### Server Side Rendering

<video controls src='https://www.shivamjha.io/static/videos/react-server-components/ssr.mp4'>
  Sorry, your browser doesn't support embedded videos, but don't worry, you can
  <a href='https://www.shivamjha.io/static/videos/react-server-components/ssr.mp4'>download it</a>
  and watch it with your favorite video player!
</video>

### React Server Components

<video controls src='https://www.shivamjha.io/static/videos/react-server-components/rsc.mp4'>
  Sorry, your browser doesn't support embedded videos, but don't worry, you can
  <a href='https://www.shivamjha.io/static/videos/react-server-components/rsc.mp4'>download it</a>
  and watch it with your favorite video player!
</video>

## When I should use React Server Components ?

- One of the main use cases of RSC(s) is that you can use a large-size library (like for markdown or for date formatting, etc.) in your server, while having **zero** impact on your bundle size.

  ```jsx
  import Foo from 'my-heavy-library'

  // Component that consumes Foo
  function Bar() {
    // ...Do something
  }
  ```

  ```jsx
  // Same library, but with Server Components, zero bundle size
  import Foo from 'my-heavy-library'

  // Same component
  function Bar() {
    // ...Do something
  }
  ```

- At other times, you might want to use `env` variables to access some keys, or do data fetching from your DB. You can do all that with RSC, without leaking anything in the browser source. (Well, you could do the same thing with SSR). As a general rule of thumb, if you want to use Server Resources directly, and don't want them to leak on the client, you can [fetch data inside Server Components](https://beta.nextjs.org/docs/data-fetching/fetching#asyncawait-in-server-components).

  ```jsx
  async function getData() {
    const res = await fetch('https://api.example.com/...', {
      key: process.env.MY_SECRET_KEY,
    })
    // The return value is *not* serialized
    // You can return Date, Map, Set, etc.

    // Recommendation: handle errors
    if (!res.ok) {
      // ...
    }

    return res.json()
  }

  // Server Component
  export default async function Page() {
    const data = await getData()

    return <main></main>
  }
  ```

- Using RSC, you can make sure that there are no Client Network Waterfalls. (The issue when JavaScript needs to be downloaded before a component can even start fetching data - If that component is nested deep in the component tree and parent component needs some data, then data fetching cannot even start before the child is rendered if traditional client-side rendering is used). Some libraries like [Tanstack Query](https://tanstack.com/query/) and [React Router](https://reactrouter.com/) makes this easier by prefetching data. But still, in case of client-only rendering, you cannot fetch data before your JavaScript is downloaded.

## When not to use Server Components ?

- Server components cannot have any interactivity (`onClick`, `onScroll`, etc.) and can only be used for generating plain HTML stuff. For interactivity, you have to use what are now called [Client Components](https://beta.nextjs.org/docs/rendering/server-and-client-components#client-components).

- Server Components cannot have state (`useState`) or use Side Effects (`useEffect`, etc). (Since the cannot have interactivity). Or custom hooks that depend on combination of state and effects.

- Since they run on server, and server only, they cannot use browser APIs (like `localStorage`, etc.)

For a full comparison, check out [Next.js docs for `app` directory](https://beta.nextjs.org/docs/rendering/server-and-client-components#when-to-use-server-vs-client-components)

## Okay, how do I use them in my app ?

- Back in October 2022, [Next 13 was released with support for Server Components](https://nextjs.org/blog/next-13#server-components). You can check out [beta Next.js Docs](https://beta.nextjs.org/docs/rendering/server-and-client-components) if you want to try out RSC in your existing Next.js Applications. It is still experimental (at the time of writing this blog)

- In case of Remix, seems they are not transitioning yet to RSC. Checkout this [blog explaining React Server Components and Remix](https://remix.run/blog/react-server-components). Btw, Remix already solved the problems that RSC solves. With [Remix Loaders](https://remix.run/docs/en/v1/guides/data-loading), you can fetch data in the Server, and this will be run only on the server, without being shipped to the client. Components server-rendered by Remix can have interactivity (in terms of state and side-effects). Also, Remix comes with [built-in mechanism for de-duping requests, handling race conditions & fetch cancellations](https://remix.run/docs/en/v1/guides/api-routes#call-loaders-outside-of-navigation)