Menu
Coddy logo textTech

Серверный компонент внутри клиентского

Часть раздела Основы Next.js путешествия по React на Coddy — урок 21 из 47.

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

Клиентский компонент не может импортировать серверный компонент: импорт перетягивает его через границу, и он тоже становится клиентским кодом. Поэтому люди приходят к выводу, что всё внутри интерактивной обёртки должно быть клиентским кодом. Этот вывод неверен.

Клиентский компонент может рендерить серверный контент, переданный ему в качестве children.

Разница заключается в том, кто выполняет рендеринг. Когда серверная страница пишет это:

<Panel>
    <Details />
</Panel>

server рендерит <Details /> и передаёт готовый результат в Panel в качестве пропа. Panel никогда не импортирует его, никогда не запускает: он просто решает, куда его поместить. Что касается client компонента, children — это уже готовый фрагмент UI.

Это то, что позволяет небольшой интерактивной оболочке (переключателю вкладок, модальному окну, сворачиваемой панели) обёртывать большие объёмы контента, предназначенного только для сервера, не перенося ничего из этого в браузер. Интерактивная часть остаётся крошечной, а контент остаётся на сервере.

Форма, которую нужно запомнить: client-обёртки, server-начинки.

challenge icon

Задание

Средне

components/Panel.jsx — это клиентский компонент (заблокирован, ознакомьтесь с ним): он рендерит кнопку переключения и показывает свои children только в открытом состоянии.

Прямо сейчас страница рендерит детали рядом с панелью, а не внутри неё, поэтому переключатель ничего не контролирует.

  1. В app/page.jsx переместите <p id="details"> так, чтобы он располагался между тегами <Panel> в качестве его children.
  2. Оставьте текст точно в таком виде, как он есть, и оставьте app/page.jsx серверным компонентом: без директивы.

Абзац по-прежнему рендерится на сервере. Клиентская панель только решает, показывать ли его.

Попробуйте сами

import './globals.css';

export const metadata = {
    title: 'My App',
};

export default function RootLayout({ children }) {
    return (
        <html lang="en">
            <body>
                {children}
            </body>
        </html>
    );
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Основы Next.js