Откуда приходят данные при серверной генерации в Next.js
Что проверяют
Знаете ли вы актуальную модель получения данных в Next.js и понимаете ли, что именно выполняется на сервере. Вопрос быстро разводит тех, кто работал с маршрутизатором на серверных компонентах, и тех, кто помнит только функции из времён каталога pages.
Как отвечать
В App Router данных, приходящих откуда-то сверху, нет: серверный компонент сам асинхронный и запрашивает то, что ему нужно.
export default async function Page() {
const res = await fetch("https://api.example.com/items");
const items = await res.json();
return <List items={items} />;
}Источником может быть внешний API, соседний сервис, а может и база напрямую через ORM: код серверного компонента в браузерный бандл не попадает, поэтому ключи и строка подключения остаются на сервере.
Дальше важное про кэш и режим рендера:
- одинаковые вызовы
fetchв рамках одного рендера дедуплицируются; - в свежих версиях результат
fetchпо умолчанию не кэшируется, кэш и срок его жизни включаются явно; - обращение к
cookies,headersили к параметрам строки запроса переводит маршрут в динамический рендер, причём для всей ветки, включая макет; - для статики на динамическом сегменте нужен список параметров из
generateStaticParams; - медленные части оборачиваются в
Suspense, и страница уходит потоком.
Если спросят про старый маршрутизатор, назовите getServerSideProps для запроса на каждый заход и getStaticProps для сборки, но сразу оговоритесь, что в App Router их нет.
Где спотыкаются
Ходят из серверного компонента в собственный маршрут API по сети. Это лишний круг через HTTP: функцию, которая читает данные, можно вызвать напрямую.
Пробуют получить данные хуком или эффектом внутри серверного компонента. Хуки и состояние живут только в клиентских компонентах, а клиентские компоненты не могут быть асинхронными.
Считают, что объявленный срок перепроверки работает всегда. Одно обращение к динамическому API где-то выше по дереву убивает статику для всей группы маршрутов, и страница начинает собираться на каждый запрос.