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
// Це серверний компонент (за замовчуванням) export default async function Page() { const data = await fetch('https://api.example.com/posts').then(r => r.json()); return <PostList posts={data} />; } // Це клієнтський "use client"; import { useState } from "react"; export function LikeButton() { const [liked, setLiked] = useState(false); return <button onClick={() => setLiked(!liked)}>{liked ? "heart" : "outline heart"}</button>; }

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

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

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

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

Клієнт отримує цей "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 (за замовчуванням) 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

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