Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що означає межа 'use client' у Next.js і які props можна через неї передати?

У App Router компоненти за замовчуванням серверні. Директива 'use client' на початку файлу позначає межу: цей модуль і все, що він імпортує, потрапляє в клієнтський бандл.

// app/products/[id]/page.tsx - серверний компонент
import AddToCart from './add-to-cart';

export default async function Page({ params }) {
  const { id } = await params;
  const product = await db.product.find(id);   // запит прямо в компоненті

  return (
    <>
      <h1>{product.name}</h1>
      <AddToCart productId={product.id} price={product.price} />
    </>
  );
}
// add-to-cart.tsx
'use client';

export default function AddToCart({ productId, price }) {
  const [qty, setQty] = useState(1);
  return <button onClick={() => addToCart(productId, qty)}>У кошик - {price * qty} грн</button>;
}

Що можна передати з серверного в клієнтський компонент - лише серіалізовані значення:

  • примітиви, звичайні об'єкти й масиви, Date, Map, Set, типізовані масиви;
  • Promise (клієнт розгорне через use());
  • React-елементи (JSX), зокрема children;
  • серверні функції ('use server').

Не можна: звичайні функції (обробники подій), екземпляри класів, моделі ORM з методами, символи (крім глобально зареєстрованих).

Важливі наслідки:

  • усе передане видно в браузері. Передати в клієнтський компонент повний об'єкт користувача з бази - відправити в HTML і хеш пароля, і службові поля. Передавайте лише потрібні поля;
  • межу ставлять якомога нижче - на інтерактивний «листок» (кнопка, форма), а не на всю сторінку. Інакше весь вміст і його залежності йдуть у бандл;
  • серверний компонент можна вставити в клієнтський через children, але не імпортувати в клієнтський модуль напряму - імпорт перетворить його на клієнтський;
  • контекст і провайдери (ThemeProvider) - клієнтські компоненти, що обгортають children у макеті;
  • бібліотеки без 'use client', що використовують хуки, треба обгорнути у власний клієнтський модуль.

'use client' - не «рендер лише в браузері». Клієнтські компоненти теж рендеряться на сервері при першому завантаженні (SSR), а потім гідруються. Тому в їхньому рендері не можна звертатися до window без перевірок.

Докладніше в документації: Next.js: серверні й клієнтські компоненти

Схожі питання