React Server Components ... React magic feature!! 🔮
Tags: react, nextjs, webdev, development
Published: 2024-03-10 16:51:18


To understand the benefits of RSCs, I will briefly talk about **Server Side rendering (SSR)** and **Suspense boundary**.

**SSR** works on initial page load (When directly navigating to the page) by sending the pre-rendered HTML to the client which will be hydrated with the downloaded JavaScript to be fully interactive. However, with SSR the data must be fetched in the server before React can show any pre-rendered HTML. Also, all JavaScript should be downloaded on the client side before starting the hydration and the hydration process should be completed before the page can become interactive.

To solve these issues, React introduced **Suspense**, which brings both server-side HTML streaming and selective hydration. So, by wrapping any component (generally heavy components) with <Suspense>, we are telling React to deprioritize that component's rendering and hydration, which will cause in loading other components without getting blocked by the heavier ones. However, even after using Suspense we still need to download all JavaScript to the client even if it's streamed to the browser asynchronously. Also, all heavy components will continue to be computed on the client.

By introducing **React Server Components**, React can now solve all the previous issue:
🌟 Now we can move all heavy components to the server (which is powerful and physically closer to data sources) by using RSCs which will individually fetch data and then will be rendered entirely on the server. After that, the result of that rendering will be streamed into the client-side (React component tree), removing the need for client-side re-rendering.
🌟 The result of rendering RSC on the server will be React Server Component Payload which contains beside the rendered result of RSC: a placeholders to define where Client Components should be rendered, the references to their JavaScript files and any props passed from a Server Component to a Client Component. Which will reduce the size of the client-side JavaScript bundle by resolving all dependencies on the server and sending only RSC Payload.
🌟 Regarding Client Components, the hydration will happen concurrently with RSCs streaming in, because the compute load will be shared between client and server.
🌟 Even when an RSC needs to be re-rendered because of state change, No hard refresh will be needed as RSC will be refreshed on the server and seamlessly merges into the existing DOM. Which will preserve the client state even if server components are updated from the server.


![RSC Example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ttl1myf13tll2cq83jam.png)

💡 All code written for Server Components must be serializable, which means that we can’t use lifecycle hooks, such as useState or useEffect.

💡 RSC does not replace SSR or Suspense, but it works with them to provide the best performance possible.

💡 Typically we are using Server Components at the root level and it is preferred to fetch data in the Server Components (Server is physically closer to data sources and more powerful than client devices), then we can pass the result to other Server Component or to a Client Component if we need to use event handlers or lifecycle hooks.

💡 We cannot import a Server Component into a Client Component but instead we can pass Server Components as a prop to a Client Component (usually using React children prop).


![Passing Server Components as a prop to a Client Component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bq7d2z548jw7fjgzbsfe.png)

💡 We can use RSCs with Next.js starting from version 13.4 (App Router).



🎉🎉 [Project on GitHub]: Nextjs 14 with App Router, Fully authentication using NextAuth ... (https://github.com/alaa-m1/nextjs14-approuter-nextauth-shopsfinder)