Что такое React Server Components
▸Концепция
React Server Components (RSC) — компоненты, которые рендерятся на сервере и отправляют клиенту только результат. Они не добавляют JavaScript в bundle.
▸Server vs Client компоненты
По умолчанию все компоненты в App Router Next.js — Server Components. Для клиентского рендера используется директива 'use client'.
1// Server Component (по умолчанию)2async function UserProfile({ userId }) {3 const user = await db.user.findById(userId);4 return <div>{user.name}</div>;5}67// Client Component8'use client';9function Counter() {10 const [count, setCount] = useState(0);11 return <button onClick={() => setCount(c => c + 1)}>{count}</button>;12}
Преимущества Server Components
▸Нулевой bundle size
Server Components не отправляют JavaScript на клиент. Они рендерятся на сервере и возвращают HTML/RSC payload.
▸Прямой доступ к базе данных
Серверные компоненты могут напрямую работать с базой данных, файловой системой и другими серверными ресурсами.
1// Прямой запрос к БД — безопасно на сервере2async function Products() {3 const products = await db.product.findMany();4 return (5 <ul>6 {products.map(p => <li key={p.id}>{p.name}</li>)}7 </ul>8 );9}
▸Автоматическое разделение кода
React автоматически разделяет server и client части. Клиентский bundle содержит только интерактивные компоненты.
Когда использовать 'use client'
▸Интерактивность
Компоненты с useState, useEffect, обработчиками событий должны быть клиентскими.
1'use client';2import { useState } from 'react';34function SearchInput({ onSearch }) {5 const [query, setQuery] = useState('');6 return (7 <input8 value={query}9 onChange={e => {10 setQuery(e.target.value);11 onSearch(e.target.value);12 }}13 />14 );15}
▸Browser APIs
Компоненты, использующие window, document, localStorage — клиентские.
1'use client';2function ThemeToggle() {3 const [theme, setTheme] = useState('light');4 useEffect(() => {5 document.body.className = theme;6 }, [theme]);7 return <button onClick={() => setTheme(t => t === 'light' ? 'dark' : 'light')}>Toggle</button>;8}
Паттерны использования
▸Разделение ответственности
Server Components берут данные, Client Components — интерактивность:
1// Server: загружает данные2async function ProductPage({ params }) {3 const product = await getProduct(params.id);4 return (5 <div>6 <h1>{product.name}</h1>7 <ProductActions productId={product.id} />8 </div>9 );10}1112// Client: интерактивность13'use client';14function ProductActions({ productId }) {15 const [quantity, setQuantity] = useState(1);16 return (17 <div>18 <button onClick={() => setQuantity(q => q - 1)}>-</button>19 <span>{quantity}</span>20 <button onClick={() => setQuantity(q => q + 1)}>+</button>21 <button onClick={() => addToCart(productId, quantity)}>В корзину</button>22 </div>23 );24}
▸Composition паттерн
Передавайте Client Components как children в Server Components:
1// Server Component2async function Layout({ children }) {3 const data = await fetchData();4 return (5 <div>6 <Header data={data.header} />7 {children}8 </div>9 );10}
Ограничения
▸Нельзя использовать хуки
Server Components не поддерживают React Hooks. Используйте 'use client' для компонентов с состоянием.
▸Нельзя передавать функции в пропсы
Server Components не могут передавать функции клиентским компонентам через пропсы. Используйте Server Actions для обратного вызова.
▸Ограниченная совместимость библиотек
Не все библиотеки совместимы с RSC. Проверяйте документацию перед использованием.
Server Actions
▸Определение
1'use server';2async function addToCart(productId: string, quantity: number) {3 await db.cart.add({ productId, quantity });4 revalidatePath('/cart');5}
▸Использование в Client Components
1'use client';2function AddToCartButton({ productId }) {3 return (4 <form action={addToCart}>5 <input type="hidden" name="productId" value={productId} />6 <button type="submit">В корзину</button>7 </form>8 );9}
Производительность
▸Сравнение с традиционным SSR
RSC уменьшает клиентский JavaScript, ускоряет First Contentful Paint и Time to Interactive.
▸Кэширование
1// Кэширование запросов2const products = await cache(3 () => db.product.findMany(),4 ['products']5);
Заключение
React Server Components — это парадигма. Они уменьшают bundle size, упрощают доступ к серверным ресурсам и улучшают производительность. Next.js App Router построен вокруг RSC. Изучите эту концепцию — она станет стандартом React-разработки.