Modern apps require a lot of time researching, designing, developing, and testing. There are a lot of different techniques that can be used for building modern apps, each of these techniques is for solving specific problems, and each one of them has its pros and cons. There’s no silver bullet for building modern apps.
When working with React, we can name a few different techniques that are used nowadays, but the most used are server-side rendering and client-side rendering. Both of these techniques solve specific problems and are the most used by developers for building rich modern apps.
At the end of 2020, the React team proposed a new feature of React called React Server Components. Since then, the React community has started to discuss the pros and cons of this new way of building React applications and how it can impact the future of React apps.
We are going to cover React Server Components and how they will change the modern way of building React apps.
React Server Components
Before learning more about React Server Components, keep in mind that it’s still under development and is not recommended to be used in production yet.
From the React team:
Server components allow developers to build apps that span the server and client, combining the rich interactivity of client-side apps with the improved performance of traditional server rendering.
React Server Components will have zero impact on the bundle-size and it will likely change how we build React apps. It will not only reduce the bundle-size itself but will also improve the initial page load time.
React Server Components are rendered on the server and only the rendered content is sent to the client:
import db from "database"; const Comment = (props) => { const { id } = props; const comment = db.comments.get(id); return ( <div> <h1>{comment.title}</h1> <p>{comment.text}</p> </div> ); };
A React Server Component looks like a traditional React component, it takes in props and has a render method. It only has a few additional capabilities, such as:
- They can directly access server data sources such as microservices, functions, database, etc. The possibilities that this capability opens is huge, we will be able to create internal APIs that work with various data sources, we can have access to our server inside our component without having to expose it directly to an API.
- They are created following a working naming convention using the
.server.js
suffix after the name of the component. For example, if your component is going to be namednote.js
, it will have to benote.server.js
. Respectively, client components will be created following the naming convention using.client.js
suffix after the name of the component.
React Server Components does not solve all of the problems that we have right now. Here are a few capabilities that React Server Components does not have:
- React Server Components can’t have state because they are executed once per request, so the idea to use React hooks for handling state data such as
useState
anduseReducer
are not supported - React Server Components can’t make usage of React hooks for rendering lifecycle methods such as
useEffect
anduseLayoutEffect
- React Server Components can’t make usage of browser-only APIs
We can create React components and hooks that can be used both on our server and client components. Hooks are a very simple and powerful way for sharing logic between components and we can still make use of it with server components.
We should make sure that we are following all of the constraints including:
- We can’t make use of state logic using hooks such as useState or useReducer
- We can’t use server-side data source
- We can’t use custom hooks that depend on state, effects, or browser-only APIs
After following all of the constraints, we can create components and hooks that can be used both on server and client side.
The traditional React component is called client component, because it’s rendered on the client-side. A client component is the component that you are used to, it can handle state data, it can work with browser-only APIs, etc.
React Server Components can render server components, native HTML elements, or client components. Let’s imagine that we have a component called CommentLikeButton
, which is a client component, we can simply import it inside our server component and use it without any problem:
import db from "database"; import CommentLikeButton from 'CommentLikeButton.client'; const Comment = (props) => { const { id } = props; const comment = db.comments.get(id); return ( <div> <h1>{comment.title}</h1> <section>{comment.body}</section> <CommentLikeButton /> </div> ); };
RSC vs. SSR
Server-side rendering is a technique for rendering apps on the server-side, sending the HTML to the client and the HTML is rendered by the browser. Here’s one of the two most important advantages that server-side rendered apps have:
- Performance — The HTML file that the client receives is already filled with content and ready to be rendered, so there’s no need for the browser to fetch any JavaScript
- SEO — The SEO performance is increased due to JavaScript usually requires search engines to spend more time rendering the app. Since all the content that the client will need is rendered on the server, the file will be ready to be rendered, resulting in a better ranking search
Server Components are components that are rendered on the server-side but not as HTML. Server Components are rendered using a special format that is streamed into the client.
This is how a React Server Component is rendered:
The stream that React Server Components uses for rendering our components has no standard protocol for now but looks a lot like JSON format.
Although React Server Components are very powerful, they will not replace server-side rendered applications there are a few differences that we need to discern:
- React Server Components may be rerendered any time, while SSR apps can be rerendered but they will rerender a whole new HTML page and lose its app state (in case there’s any)
- React Server Components can access server data sources such as microservices, functions, database from anywhere in the tree, while with SSR apps, especially with Next, we need to use getServerProps() which only works at the top-level of our page
Most of the time, when we are using server-side rendering, we just use it once for initial rendering. Server components can be refetched multiple times to rerender our data. We can refetch our server components regularly and the server will stream updates down, without losing any state data on our client components.
Impact of React Server Components
Every new thing that’s released in the web development community can change the way we are building and will build modern applications in the future. Developers are always looking for new techniques for improving their apps and of course, React Server Components may bring a new way of building modern apps.
We know that React Server Components are different from server-side rendering apps, we use a special format for rendering and we also can refetch our component as many times as we want to rerender our data. Only by these two features, we can easily change the whole way we are building React applications.
With React Server Components we can have a new way of building modern applications by mixing both client and server-side rendered components, we can have only a small part of our UI server-side rendered using React Server Components and the other UI parts using traditional React components.
Although it’s a new technology, React Server Components has a lot of potential and brilliant features that will undoubtedly improve the way modern apps will be built in the future such as zero bundle-size, access data sources directly from the server, integration with client components, etc.
Conclusion
React has a lot of different techniques for building modern apps and React Server Components are a very powerful technique for rendering components on the server-side and only sending the content to the client. As we saw, server components are still a little bit different from server-side rendered apps and it has a few different capabilities. Server components are still in research and development by the React team but we can predict that the future is very bright for React apps, allowing developers to make a mix of server-side rendered and client-side rendered components together, improving the client experience and the app performance.
Get setup with LogRocket's modern React error tracking in minutes:
- Visit https://logrocket.com/signup/ to get an app ID.
- Install LogRocket via NPM or script tag.
LogRocket.init()
must be called client-side, not server-side. - (Optional) Install plugins for deeper integrations with your stack:
- Redux middleware
- ngrx middleware
- Vuex plugin
$ npm i --save logrocket
// Code:
import LogRocket from 'logrocket';
LogRocket.init('app/id');
Add to your HTML:
<script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
<script>window.LogRocket && window.LogRocket.init('app/id');</script>