Коротка відповідь
Server Components підходять для серверного читання й неінтерактивного рендерингу, Client — для стану, подій, effects і браузерних API. use client задає межу графа залежностей, не візуальну позначку. Розміщуйте її біля інтерактивного елемента й передавайте мінімальні дані.
Практичні кроки реалізації
1. Визначте браузерну можливість
Заголовку й опису не потрібен клієнтський стан; кнопці розкриття потрібні подія та стан, геолокації — API й дозволи. Позначте найменший відповідний модуль. use client на сторінці через одну кнопку може втягнути непотрібні залежності.
2. Спроєктуйте дані межі
React серіалізує значення між сервером і клієнтом. Підтримка ширша за JSON, але довільні функції й класи не є універсальними props. Передавайте публічні поля, не весь рядок бази чи ключ. ID визначає операцію, яку сервер усе одно авторизує.
3. Передавайте серверний результат у клієнтські slots
Server Component може передати відрендерований контент як children клієнтській оболонці. Оболонка не імпортує серверний модуль, тож залежність не переходить у її граф. Це зручно для modal. Переданий HTML чи props усе одно доступний користувачу.
4. Врахуйте початковий рендеринг
Client Component може входити до початкового HTML перед гідратацією. Не читайте window чи localStorage під час render лише через use client. Використайте effect або подію й стабільний початковий вигляд. Приховування hydration-попереджень не виправляє розбіжність.
Приклад реалізації
Це локальний елемент, який не зберігає обране. Серверна сторінка передає початкові публічні дані. Для збереження додайте серверну операцію й стани очікування, відмови та повтору. Відображення відрізняється від авторитетного запису.
// app/components/favorite-toggle.tsx
"use client";
import { useState } from "react";
export function FavoriteToggle({ initial }: { initial: boolean }) {
const [selected, setSelected] = useState(initial);
return (
<button type="button" aria-pressed={selected}
onClick={() => setSelected((previous) => !previous)}>
{selected ? "Remove favorite" : "Add favorite"}
</button>
);
}
Компроміси та альтернативи
Клієнтський стан доречний для тимчасових виборів і браузерних можливостей; сервер — для привілейованого читання й неінтерактивних залежностей. Provider може об’єднати елементи, але не обов’язково весь документ. Обсяг стану визначається взаємодією, не числом Server Components.
Поширені помилки
Не імпортуйте базу в client, покладаючись на назву файла. Не передавайте секрети через props. Не викликайте звичайний async Server Component із клієнтського модуля. Серверний рендеринг не скасовує авторизацію, а прихована кнопка не блокує прямий endpoint.
Перевірка перед випуском
- Кожен use client має браузерну причину.
- Props містять лише потрібні публічні дані.
- Браузерні читання не виконуються при prerender.
- Імпорти відповідають середовищу.
- Взаємодія доступна клавіатурою.
- Записи окремо перевіряють дозвіл.
Поширені запитання
Чи use server протилежний use client?
Ні. use server позначає Server Functions, не звичайні Server Components. У App Router немарковані pages і layouts серверні за замовчуванням. Межа мутації відрізняється від середовища рендерингу.
Чи може client містити серверний контент?
Так, якщо серверний батько передає результат через children чи інший prop. Це відрізняється від імпорту серверного модуля всередині client.
Наступний крок
Намалюйте клієнтський граф маршруту, наблизьте директиву до елементів, перевірте приватні поля props і гідратацію. Виміряйте browser output до тверджень про виграш швидкодії.
Первинні джерела
Пов’язані матеріали та приклади
Потрібно реалізувати це у вашому продукті?
Перегляньте відповідні приклади продуктів або поділіться контекстом розробки вебзастосунку, розширення Chrome, API чи SaaS.