Клиентские компоненты

Клиентские компоненты позволяют создавать интерактивный интерфейс, который предварительно рендерится на сервере и может использовать клиентский JavaScript для работы в браузере.

На этой странице объясняется, как работают клиентские компоненты, как они рендерятся и когда их стоит использовать.

Преимущества рендеринга на клиенте

Рендеринг на стороне клиента имеет несколько преимуществ, включая:

  • Интерактивность: Клиентские компоненты могут использовать состояние, эффекты и обработчики событий, что позволяет им мгновенно реагировать на действия пользователя и обновлять интерфейс.
  • Браузерные API: Клиентские компоненты имеют доступ к браузерным API, таким как геолокация или localStorage.

Использование клиентских компонентов в Next.js

Чтобы использовать клиентские компоненты, добавьте директиву React "use client" в начало файла, перед импортами.

Директива "use client" объявляет границу между модулями серверных и клиентских компонентов. Это означает, что при определении "use client" в файле все импортируемые в него модули, включая дочерние компоненты, считаются частью клиентского бандла.

'use client'

import { useState } from 'react'

export default function Counter() {
  const [count, setCount] = useState(0)

  return (
    <div>
      <p>Вы кликнули {count} раз</p>
      <button onClick={() => setCount(count + 1)}>Нажми меня</button>
    </div>
  )
}
'use client'

import { useState } from 'react'

export default function Counter() {
  const [count, setCount] = useState(0)

  return (
    <div>
      <p>Вы кликнули {count} раз</p>
      <button onClick={() => setCount(count + 1)}>Нажми меня</button>
    </div>
  )
}

На диаграмме ниже показано, что использование onClick и useState во вложенном компоненте (toggle.js) вызовет ошибку, если не определена директива "use client". Это связано с тем, что по умолчанию все компоненты в App Router являются серверными, где эти API недоступны. Определив директиву "use client" в toggle.js, вы сообщаете React, что нужно войти в клиентскую границу, где эти API доступны.

Директива Use Client и сетевая граница

Определение нескольких точек входа use client:

Вы можете определить несколько точек входа "use client" в дереве React-компонентов. Это позволяет разделить приложение на несколько клиентских бандлов.

Однако не нужно определять "use client" в каждом компоненте, который должен рендериться на клиенте. После определения границы все дочерние компоненты и импортируемые модули считаются частью клиентского бандла.

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

В Next.js клиентские компоненты рендерятся по-разному в зависимости от того, является ли запрос частью полной загрузки страницы (первоначальный визит в приложение или перезагрузка страницы) или последующей навигации.

Полная загрузка страницы

Для оптимизации первоначальной загрузки страницы Next.js использует API React для рендеринга статического HTML-превью на сервере как для клиентских, так и для серверных компонентов. Это означает, что при первом посещении приложения пользователь сразу увидит содержимое страницы, не дожидаясь загрузки, парсинга и выполнения JavaScript-бандла клиентских компонентов.

На сервере:

  1. React рендерит серверные компоненты в специальный формат данных под названием React Server Component Payload (RSC Payload), который включает ссылки на клиентские компоненты.
  2. Next.js использует RSC Payload и инструкции JavaScript клиентских компонентов для рендеринга HTML маршрута на сервере.

Затем на клиенте:

  1. HTML используется для немедленного отображения быстрого неинтерактивного превью маршрута.
  2. React Server Components Payload используется для согласования деревьев клиентских и серверных компонентов и обновления DOM.
  3. Инструкции JavaScript используются для гидратации клиентских компонентов и обеспечения их интерактивности.

Что такое гидратация?

Гидратация — это процесс присоединения обработчиков событий к DOM для обеспечения интерактивности статического HTML. Внутри гидратация выполняется с помощью API React hydrateRoot.

Последующая навигация

При последующей навигации клиентские компоненты рендерятся полностью на клиенте, без серверного HTML.

Это означает, что JavaScript-бандл клиентских компонентов загружается и парсится. Как только бандл готов, React использует RSC Payload для согласования деревьев клиентских и серверных компонентов и обновления DOM.

Возврат в серверное окружение

Иногда после объявления границы "use client" может потребоваться вернуться в серверное окружение. Например, для уменьшения размера клиентского бандла, получения данных на сервере или использования API, доступного только на сервере.

Вы можете оставить код на сервере, даже если он теоретически вложен в клиентские компоненты, чередуя клиентские и серверные компоненты, а также используя серверные действия. Подробнее см. на странице Паттерны композиции.