Menu
Coddy logo textTech

Асинхронные компоненты

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

Вот результат всего, что мы подготавливали в прошлой главе. Серверный компонент может быть async:

import { getDishes } from '../lib/data';

export default async function Page() {
    const dishes = await getDishes();

    return <h1>{dishes.length} dishes</h1>;
}

Прочитайте это ещё раз, потому что это действительно кое-что новое. Компонент ждёт. Next.js запускает его на сервере, даёт await завершиться и только потом превращает результат в HTML.

Сравните это с версией только для браузера, которую вам пришлось бы написать в противном случае:

  • Страница сначала рендерится пустой
  • Запрос отправляется после того, как страница загрузилась
  • Некоторое состояние меняется, и появляется содержимое — мерцание, которое пользователь видит каждый раз

С async server компонентом нет первого пустого рендера. Нечему мерцать, потому что data уже была там, когда создавался html. Никаких useEffect, никаких флагов загрузки, никакого второго запроса.

Два правила делают это допустимым:

  • Только server компоненты могут быть async: компонент с пометкой 'use client' не может им быть
  • Данные должны поступать из места, доступного серверу: базы данных, файла или модуля вроде lib/data.js
challenge icon

Задание

Легко

Файл lib/data.js предоставлен и заблокирован. Он экспортирует getDishes(), которая возвращает промис для массива объектов { id, name }.

  1. Сделайте Page в app/page.jsx асинхронной функцией (async).
  2. Сохраните результат await getDishes() в переменную dishes.
  3. Внутри <ul id="dish-list"> отрендерите по одному елементу <li> для каждого блюда с key={dish.id}, id={dish.id} и name блюда в качестве текста.

Никаких useEffect, никакого флага загрузки, только await.

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

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