> Какая проблема при вызове fetch напрямую в компоненте Next.js (JavaScript, Next.js)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Библио-Глобус

Стек: JavaScript, Next.js

> Пример ответа

Короткий ответ

Прямой вызов fetch в компоненте Next.js без серверного рендеринга или статической генерации приводит к выполнению запроса на клиенте, что увеличивает время загрузки, снижает SEO и может вызвать проблемы с hydration. В Next.js рекомендуется использовать серверные компоненты, getServerSideProps, getStaticProps или generateStaticParams для данных, которые должны быть доступны при рендеринге.

Подробное объяснение

Основная проблема - нарушение архитектурных принципов Next.js. При прямом вызове fetch внутри клиентского компонента (например, в useEffect) данные загружаются асинхронно после монтирования компонента, что приводит к:

  • Потере SSR/SSG: запрос выполняется только на клиенте, сервер не участвует в подготовке данных, поэтому страница рендерится без контента, а затем дозагружается.
  • Снижению SEO: поисковые роботы не дожидаются выполнения fetch, видят пустой или неполный контент.
  • Проблемам с hydration: если серверный рендер и клиентский результат не совпадают, Next.js выдаёт ошибки hydration mismatch.
  • Увеличению времени до интерактивности (TTI): пользователь видит пустую страницу или skeleton, пока не выполнится запрос.

В Next.js данные должны быть получены на этапе сборки (SSG) или на сервере (SSR) через специальные методы, а не в рантайме клиента, если это не критично для динамики.

На практике

Для статических страниц используй getStaticProps с revalidate для инкрементальной регенерации. Для динамических - getServerSideProps или серверные компоненты с async и fetch на уровне модуля. Клиентский fetch оправдан только для данных, которые меняются после загрузки страницы (например, live-обновления, user-specific content после авторизации).

Пример кода

JAVASCRIPT
// ❌ Плохо: клиентский fetch в useEffect
export default function Page() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('/api/data').then(r => r.json()).then(setData);
}, []);
return <div>{data?.title}</div>;
}
// ✅ Хорошо: серверный компонент с fetch
export default async function Page() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return <div>{data.title}</div>;
}

Как отвечать на собеседовании

Начни с ключевой проблемы - потеря SSR/SSG и SEO. Затем объясни, как Next.js обрабатывает данные: серверные компоненты, getStaticProps/getServerSideProps. Упомяни, что клиентский fetch допустим для real-time данных или после авторизации, но не для основного контента. Приведи пример разницы в подходах. Покажи понимание trade-off между производительностью и динамикой.

Что проверяет интервьюер

  • Понимание архитектуры Next.js: различие между серверным и клиентским рендерингом.
  • Знание методов получения данных: getStaticProps, getServerSideProps, серверные компоненты.
  • Осознание последствий: SEO, hydration, производительность.
  • Умение выбирать правильный подход под задачу.

Типичные ошибки

  • Утверждение, что fetch в компоненте всегда плох - не учитывают случаи с динамическими данными.
  • Путаница между клиентскими и серверными компонентами в App Router.
  • Игнорирование revalidate и ISR при обсуждении SSG.
  • Предложение использовать getInitialProps в современных версиях Next.js (устарел).

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью