Содержание

React Server Components (RSC) — это компоненты, которые выполняются только на сервере: они могут напрямую обращаться к базе данных и API, а в браузер отправляется только результат, без их кода. Интерактивные части по-прежнему пишутся клиентскими компонентами. Главная выгода — меньше JavaScript в браузере и проще загрузка данных; цена — новая модель мышления и более сложная отладка кеширования.

Разберём, чем RSC отличаются от привычного SSR, как разделять серверные и клиентские компоненты и когда переход оправдан.

Чем серверные компоненты отличаются от SSR?

При обычном серверном рендеринге (SSR) весь код страницы выполняется на сервере для получения HTML, а затем тот же код загружается в браузер и выполняется снова — происходит гидратация. С серверными компонентами код части компонентов вообще не попадает в браузер: на клиент приходит только результат их работы.

Критерий Классический SSR React Server Components
Где выполняется код На сервере и затем в браузере Серверные — только на сервере
JavaScript в браузере Код всех компонентов страницы Только клиентские компоненты
Загрузка данных Отдельные функции страницы или запросы с клиента Прямо в компоненте через async/await
Доступ к базе и секретам Только в специальных функциях В любом серверном компоненте

Про серверный рендеринг в целом — статьи SEO для сайтов на JavaScript и Nuxt или Next.js.

Как разделять серверные и клиентские компоненты?

По умолчанию в App Router компоненты серверные. Клиентским компонент становится, когда в начале файла указана директива 'use client', — это нужно для состояния, обработчиков событий и браузерных API. Хорошее правило: серверные компоненты загружают данные и собирают страницу, клиентские — отвечают за интерактивность и находятся как можно ниже в дереве.

// app/products/[id]/page.tsx — серверный компонент
export default async function ProductPage({ params }: { params: { id: string } }) {
  const product = await db.product.findUnique({ where: { id: params.id } })

  return (
    <article>
      <h1>{product.title}</h1>
      <p>{product.description}</p>
      <AddToCartButton productId={product.id} />
    </article>
  )
}

// components/AddToCartButton.tsx — клиентский компонент
'use client'
export function AddToCartButton({ productId }: { productId: string }) {
  const [pending, setPending] = useState(false)
  // ...
}

Смартфон и мониторы с кодом на столе разработчика Фото: Unsplash

Какие проблемы решают серверные компоненты?

Серверные компоненты решают три проблемы: слишком много JavaScript в браузере, каскады запросов за данными и утечку логики доступа к данным на клиент.

  • меньше JavaScript — тяжёлые библиотеки для разметки текста, форматирования дат или подсветки кода остаются на сервере;
  • проще загрузка данных — компонент сам получает нужные ему данные, без промежуточного API для каждой страницы;
  • безопасность — запросы к базе и секретные ключи физически не попадают в браузер;
  • потоковая отдача — страница показывается по частям по мере готовности данных.

Для изменения данных используются Server Actions — функции, которые вызываются из формы на клиенте, а выполняются на сервере. Они удобны, но к ним нужно относиться как к публичному API: проверять права и входные данные.

Какие подводные камни есть у RSC?

Основные сложности — новая модель мышления, кеширование и граница между сервером и клиентом. Команды, привыкшие к классическому React, часто сталкиваются с неочевидными ошибками в первые недели.

  1. Граница сериализации. В клиентский компонент из серверного можно передать только сериализуемые данные — не функции и не классы.
  2. Кеширование. Фреймворк кеширует запросы и страницы на нескольких уровнях; важно понимать, когда данные обновятся.
  3. Библиотеки. Не все библиотеки работают в серверных компонентах — особенно те, что используют контекст и состояние.
  4. Отладка. Ошибки возникают то на сервере, то в браузере, нужна хорошая настройка логов.
  5. Безопасность Server Actions. Каждое действие — это открытая точка входа, которой нужны проверки прав — подробнее в статье OWASP Top 10 простыми словами.

Стоит ли переходить на серверные компоненты?

Переход оправдан для новых проектов на Next.js и для сайтов, где много контента и мало интерактивности: каталогов, медиа, документации, маркетинговых страниц. Для насыщенных интерактивных приложений вроде редакторов и дашбордов выигрыш меньше — большая часть кода всё равно останется клиентской.

  • новый проект на React с публичными страницами — начинайте с App Router;
  • существующее приложение — переносите постепенно, начиная со страниц с данными;
  • админка и внутренние инструменты — переход не обязателен;
  • команда без опыта — заложите время на обучение и договорённости.

Про выбор фреймворка — статья Vue или React: как выбрать.

Коротко

  • Серверные компоненты выполняются только на сервере, их код не попадает в браузер.
  • Клиентские компоненты с 'use client' отвечают за интерактивность и должны быть как можно ниже в дереве.
  • RSC уменьшают JavaScript, упрощают загрузку данных и прячут доступ к базе на сервере.
  • Подводные камни — граница сериализации, кеширование, совместимость библиотек и безопасность Server Actions.
  • Переход выгоден для контентных сайтов и новых проектов, для интерактивных приложений — меньше.

Частые вопросы

  • Можно ли использовать серверные компоненты без Next.js?

    Технически да, но серверным компонентам нужна поддержка в сборщике и маршрутизаторе. Next.js с App Router — самый зрелый вариант; поддержка в других фреймворках появляется, но пока менее распространена.

  • Нужно ли переписывать существующее приложение?

    Нет. Старые компоненты можно пометить как клиентские и переносить на серверные постепенно, начиная со страниц, где много данных и мало интерактивности.

  • Влияют ли серверные компоненты на SEO?

    Положительно: контент приходит готовым HTML, а меньший объём JavaScript улучшает метрики скорости. Но такого же результата для SEO можно добиться и обычным серверным рендерингом.