Skip to main content

Що таке React Server Components (RSC)?

1. Що таке React Server Components (RSC)

React Server Components (RSC) - це компоненти, які виконуються на сервері, а не в браузері, і при цьому інтегруються в одне дерево React із клієнтськими компонентами.

Простіше кажучи:

RSC - це спосіб рендерити частину React-застосунку на сервері, але при цьому залишати решту частини інтерактивною на клієнті, без дублювання логіки чи SSR-гідратації всього дерева.


2. Чим RSC відрізняються від SSR

КритерійSSR (Server-Side Rendering)RSC (React Server Components)
Де виконуєтьсяСервер генерує HTMLСервер генерує React-структуру (дерево)
Що надсилається клієнтуГотовий HTMLПотік серіалізованих компонентів
Що робить клієнт«Оживляє» HTML (hydration)Об'єднує серверні та клієнтські компоненти
Коли виконуєтьсяЗа кожного запитуМоже бути під час білда, фетчу або частково
Де можна писати fetchЗазвичай у getServerSidePropsПрямо всередині компонента!

Тобто SSR = «рендер HTML на сервері», а RSC = «рендер React-компонентів на сервері без HTML».


3. Як працює механізм RSC

Крок 1. Поділ на типи компонентів

RSC вводить два типи компонентів:

ТипДе виконуєтьсяЧи можна використовувати Hooks / DOM
Server ComponentЛише на серверіНе можна useState, useEffect, window, document
Client ComponentУ браузеріМожна все (хуки, DOM, події тощо)

Позначення в коді:

javascript
// This is a server component (the default) export default async function Page() { const data = await fetch('https://api.example.com/posts').then(r => r.json()); return <PostList posts={data} />; } // This is a client component "use client"; import { useState } from "react"; export function LikeButton() { const [liked, setLiked] = useState(false); return <button onClick={() => setLiked(!liked)}>{liked ? "Liked" : "Not liked"}</button>; }

Крок 2. Серверний рендер повертає не HTML, а React Payload

React Server Components не надсилають HTML. Сервер генерує потік серіалізованих React-компонентів, який називається React Flight Data.

Приклад (спрощено):

javascript
[ ["$","div",null,{"children":["Hello from server"]}], ["$","button","client:likeButton",{"children":["Liked"]}] ]

Клієнт отримує цей «JSON-потік» і збирає дерево React за допомогою RSC runtime.

Тобто на клієнт приходить не HTML, а «інструкції» для React про те, які компоненти відрисувати і які з них клієнтські.


Крок 3. Об'єднання (гібридне дерево)

На клієнті React об'єднує два світи:

  • Серверні компоненти - відрисовані заздалегідь (їхнього JS-коду навіть немає на клієнті),
  • Клієнтські компоненти - завантажуються, гідруються і стають інтерактивними.
javascript
<App> ├── <Header /> → Server Component ├── <PostList /> → Server Component │ ├── <Post /> → Server Component │ └── <LikeButton /> → Client Component └── <Footer /> → Server Component

Таким чином, клієнт отримує мінімальний JS - лише для LikeButton. Все інше вже відрендерено на сервері й не потребує гідратації.


4. Переваги RSC

ПеревагаЧому це круто
Менше JS на клієнтіКлієнту взагалі не потрібен код серверних компонентів
Немає подвійного рендера (як за SSR)RSC не потребує гідратації HTML, немає дублювання
ГібридністьМожна змішувати серверні та клієнтські компоненти в одному дереві
БезпекаСерверні компоненти не потрапляють на клієнт, не можна випадково «злити» ключі чи API-токени
Швидший рендер великих списків / данихЛогіка та запити виконуються на сервері, а не в браузері
Сумісність зі Streaming SSRМожна стрімити серверні та клієнтські частини асинхронно

5. Приклад RSC у Next.js 13+ (App Router)

javascript
// app/page.tsx - Server Component (the default) import Posts from './Posts'; export default async function Page() { const posts = await fetch('https://jsonplaceholder.typicode.com/posts').then(r => r.json()); return ( <main> <h1>Server-rendered posts</h1> <Posts posts={posts} /> </main> ); }
javascript
// app/Posts.tsx - Server Component import LikeButton from './LikeButton'; export default function Posts({ posts }) { return ( <ul> {posts.map(p => ( <li key={p.id}> {p.title} <LikeButton /> </li> ))} </ul> ); }
javascript
// app/LikeButton.tsx - Client Component "use client"; import { useState } from "react"; export default function LikeButton() { const [liked, setLiked] = useState(false); return ( <button onClick={() => setLiked(!liked)}> {liked ? "Liked" : "Not liked"} </button> ); }

Весь список постів рендериться на сервері, а кнопка «лайк» - інтерактивна, але завантажується окремим JS-чанком.


6. RSC ≠ SSR

ВідмінністьSSRRSC
Формат виводуHTMLReact Payload (інструкції)
ГідратаціяОбов'язковаНе потрібна
Де зберігається логіка данихУ «getServerSideProps» / APIПрямо в компонентах
Чи можна змішувати з клієнтськими компонентамиОбмеженоТак, гібридно
ПродуктивністьВища, ніж CSR, але потребує подвійного рендераЩе вища - менше JS і менше HTML

Підсумок

React Server Components (RSC) - це новий фундамент React, який:

  • переносить частину логіки та рендерингу на сервер,
  • залишає інтерактивність клієнту,
  • прибирає потребу в «hydration» для статичних частин,
  • зменшує розмір JS і пришвидшує завантаження сторінок,
  • і дає змогу змішувати серверний і клієнтський код в одному дереві.

Якщо SSR = «сервер генерує HTML», то RSC = «сервер генерує React-дерево». І це наближає React до universal rendering - розумної, гібридної моделі, де кожен компонент виконується там, де це вигідніше.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.