React Server Components (RSC) фундаментально изменили способ создания React-приложений. Перенося логику рендеринга на сервер, мы можем значительно уменьшить JavaScript-бандл, отправляемый клиенту, что приводит к более быстрой загрузке и лучшему пользовательскому опыту. В этой статье мы рассмотрим продвинутые паттерны и лучшие практики использования RSC в 2026 году.
Что такое Server Components?
Традиционно компоненты React полностью рендерились на клиенте (CSR) или предварительно рендерились на сервере в виде HTML (SSR) и затем гидратировались на клиенте. Server Components позволяют рендерить компоненты исключительно на сервере. Их код никогда не отправляется в браузер.
Преимущества
- Нулевой размер бандла: Зависимости, используемые в Server Components (парсеры markdown или тяжёлые библиотеки для работы с датами), остаются на сервере.
- Прямой доступ к бэкенду: Вы можете запрашивать базу данных прямо внутри компонента, не создавая API-эндпоинты.
- Автоматическое разделение кода: Client components, импортированные на стороне сервера, автоматически разделяются на отдельные чанки.
Паттерн получения данных
С RSC вы можете сделать компоненты async и ожидать данные напрямую.
// app/users/page.tsx import { db } from '@/lib/db'; export default async function UsersPage() { const users = await db.user.findMany(); return ( <main> <h1>Users</h1> <ul> {users.map((user) => ( <li key={user.id}>{user.name}</li> ))} </ul> </main> ); }
Suspense для стриминга
Поскольку получение данных может быть медленным, оберните компоненты в <Suspense>, чтобы сразу показать запасной UI, пока данные загружаются.
import { Suspense } from 'react'; import UserList from './UserList'; import LoadingSkeleton from './LoadingSkeleton'; export default function Page() { return ( <section> <h1>My Users</h1> <Suspense fallback={<LoadingSkeleton />}> <UserList /> </Suspense> </section> ); }
Чередование Server и Client Components
Один из самых запутанных аспектов — как комбинировать Server и Client компоненты.
Правило: Server Components могут импортировать Client Components. Client Components не могут напрямую импортировать Server Components. Однако вы можете передать Server Component как children в Client Component.
Паттерн «Children»
// ClientComponent.tsx 'use client'; import { useState } from 'react'; export default function ClientWrapper({ children }) { const [count, setCount] = useState(0); return ( <div onClick={() => setCount((c) => c + 1)}> Count: {count} {children} {/* This can be a Server Component! */} </div> ); }
// ServerPage.tsx import ClientWrapper from './ClientWrapper'; import ServerContent from './ServerContent'; export default function Page() { return ( <ClientWrapper> <ServerContent /> {/* This works perfectly */} </ClientWrapper> ); }
Типичные ошибки
- Использование Context в Server Components: Context — это концепция клиентской стороны. Если нужно передать данные на сервере, используйте props или специализированный кэш области запроса.
- Добавление обработчиков событий: Нельзя добавить
onClickилиonChangeк Server Component. Эта логика должна быть в Client Component — листовом узле.
Заключение
React Server Components — это не просто фича; это смена парадигмы. Понимая границу между сервером и клиентом, вы можете создавать приложения, которые одновременно высокоинтерактивны и невероятно быстры.