Как получать данные в Next.js: способы, примеры и рекомендации

Введение
Next.js — фреймворк для React, упрощающий создание серверно-рендерных и гибридных приложений. Одной из ключевых задач при разработке является получение данных (data fetching): от рендера на сервере для SEO до динамических запросов на клиенте для персонализации.
Опишем основные подходы, когда их применять, приведём рабочие примеры и добавим практические подсказки и чек-листы.
Что такое получение данных (одной строкой)
Получение данных — это запрос (обычно HTTP) к API или базе, чтобы заполнить компоненты интерфейса актуальной информацией.
Важно: выбор метода влияет на производительность, SEO, пользовательский опыт и сложность реализации.
Когда выбирать тот или иной метод — краткие эвристики
- Если данные критичны для SEO и редко меняются — используйте getStaticProps (статическая генерация).
- Если данные должны быть свежими при каждом запросе — getServerSideProps (SSR).
- Если нужна статическая страница с периодическим обновлением — ISR (Incremental Static Regeneration).
- Для персонализированных / интерактивных страниц лучше клиентский fetch (useEffect) или SWR/React Query.
Эта «карта» поможет выбрать подход до глубокого проектирования.
1. useEffect: клиентский fetch в компоненте
useEffect — хук React для побочных эффектов. Хорош для динамических данных, зависящих от состояния пользователя (например, профиль текущего пользователя).
Когда использовать
- Данные специфичны для клиента (токен в localStorage, user-specific).
- Не нужно SEO-индексирование содержимого.
Пример (корректный, минимальный):
import { useEffect, useState } from 'react';
export default function Home() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
let mounted = true;
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) throw new Error('Network response was not ok');
return response.json();
})
.then(payload => {
if (mounted) setData(payload);
})
.catch(err => {
if (mounted) setError(err);
});
return () => { mounted = false; };
}, []);
if (error) return Ошибка: {error.message};
if (!data) return Загрузка...;
return (
{data.name}
);
}Пояснения и лучшие практики
- Обрабатывайте ошибки и состояния загрузки.
- Отменяйте побочный эффект при размонтировании (флаг mounted или AbortController), чтобы избежать утечек и попыток обновить состояние несуществующего компонента.
- useEffect с пустым массивом зависимостей выполнится один раз при монтировании.
Когда этот подход не подходит
- Если вам нужен рендер с уже заполненными данными на сервере (SEO) — используйте getStaticProps или getServerSideProps.
2. SWR: автоматическое устаревание и повторная валидация
SWR — легковесная библиотека от команды Vercel для кеширования и автоматической повторной валидации данных (stale-while-revalidate). Она отлично подходит для клиентских запросов, где важно держать данные свежими без сложного состояния загрузки.
Ключевые особенности
- Автоматическая повторная валидация при фокусе окна и при восстановлении соединения.
- Кэширование, дедупликация запросов, поддержка рефетча.
Пример использования и выключение автоматической валидации:
import useSWR from 'swr';
const fetcher = (url) => fetch(url).then(res => {
if (!res.ok) throw new Error('Network error');
return res.json();
});
export default function Page() {
const { data, error, isLoading } = useSWR('https://api.example.com/data', fetcher, {
revalidateOnFocus: false,
revalidateOnReconnect: false,
});
if (error) return Ошибка: {error.message};
if (isLoading) return Загрузка...;
return {data.name};
}Советы
- По умолчанию SWR обновляет данные при возвращении фокуса и при восстановлении сети — удобно для интерактивных приложений.
- Отключайте revalidateOnFocus/revalidateOnReconnect для снижения количества запросов, если это уместно.
- SWR поддерживает связку с mutate() для оптимистичного обновления.
Когда SWR не подходит
- Если требуется строгий SSR-рендер с готовыми данными на первом байте — используйте серверные методы.
3. isomorphic-unfetch: универсальный fetch (полифилл)
isomorphic-unfetch — библиотека-полифилл, которая обеспечивает fetch как на клиенте, так и на сервере (Node). Раньше широко использовалась в проектах Next.js как кросс-платформенная обёртка вокруг fetch.
Установка:
npm install isomorphic-unfetchПример использования:
import fetch from 'isomorphic-unfetch';
import { useEffect, useState } from 'react';
export default function Home() {
const [data, setData] = useState(null);
useEffect(() => {
let mounted = true;
fetch('https://api.example.com/data')
.then(res => {
if (!res.ok) throw new Error('Network response was not ok');
return res.json();
})
.then(json => { if (mounted) setData(json); })
.catch(() => {});
return () => { mounted = false; };
}, []);
if (!data) return Loading...;
return {data.name}
;
}Примечание
- В современных версиях Next.js можно использовать встроенный fetch на сервере и клиенте; isomorphic-unfetch остаётся опцией для совместимости с очень старыми проектами.
4. Серверные методы Next.js: getStaticProps, getServerSideProps и ISR
Next.js предоставляет нативные способы получать данные на сервере:
- getStaticProps — данные собираются на этапе сборки (SSG). Отлично для страниц, где данные редко меняются.
- getServerSideProps — выполняется при каждом запросе (SSR). Подходит, когда данные должны быть актуальными для каждого запроса.
- ISR (revalidate в getStaticProps) — позволяет регенерировать статические страницы по расписанию.
Примеры:
getStaticProps (SSG):
export async function getStaticProps() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return {
props: { data },
revalidate: 60, // ISR: регенерация не чаще чем раз в 60 секунд
};
}getServerSideProps (SSR):
export async function getServerSideProps(context) {
const res = await fetch(`https://api.example.com/data?id=${context.params.id}`);
const data = await res.json();
return { props: { data } };
}Когда использовать
- SEO и первый байт: предпочитайте серверные методы.
- Высокая нагрузка на сервер: SSG + CDN/ISR эффективно снижает нагрузку.
Сравнение подходов — краткая матрица
- SEO: getStaticProps/SSR > CSR (useEffect) > SWR (для клиентского обновления поверх SSR).
- Актуальность: getServerSideProps > SWR (фоновая рефетч-логика) > ISR > SSG.
- Затраты на сервер: SSG/ISR < SSR.
- Сложность кода: useEffect/SWR < SSR/ISR (включая логику регенерации).
Мини-методика: шаги для выбора подхода
- Определите требования к SEO и первому байту (TTFB).
- Оцените частоту обновления данных.
- Определите, есть ли персонализация на стороне клиента.
- Выберите стратегию: SSG/ISR для редких изменений, SSR для постоянно меняющихся данных, CSR/SWR для персонализованных страниц.
- Добавьте кэширование и обработку ошибок.
- Напишите критерии приёмки и тесты (см. ниже).
Чек-листы по ролям
Frontend-разработчик
- Обработать состояние загрузки и ошибки.
- Использовать AbortController или флаг для отмены запросов.
- Минимизировать повторные запросы (дедупликация).
- Обеспечить доступность (aria-live для сообщений загрузки/ошибок).
Backend/Fullstack
- Предоставить стабильный API с механизмом пагинации и ETag/Last-Modified.
- Указать TTL для кэша и предусмотреть заголовки для CDN.
DevOps/Инфраструктура
- Настроить CDN для SSG/ISR.
- Мониторить SLA API и время отклика.
Критерии приёмки
- Страница рендерится без ошибок при отключённом JS (если требуется SSR/SSG).
- Для клиентских запросов: при медленном соединении показывается индикатор загрузки.
- Ошибки сетевых запросов отображаются человекочитаемым сообщением.
- Кеширование/реvalidация настроены и протестированы (при использовании ISR/SWR).
Примеры негативных сценариев / когда подход не сработает
- useEffect: не подходит для SEO-страниц; поисковые боты могут не увидеть содержимое, если нет серверного рендера.
- SWR: если приложение требует строжайшей консистентности данных в реальном времени (например, биржевые котировки), SWR может быть недостаточна без дополнительного механизма пуш-оповещений.
- isomorphic-unfetch: устаревший подход для новых проектов, где встроенный fetch Next.js достаточно.
Безопасность и приватность
- Никогда не включайте секреты (API keys) в клиентский код.
- Для приватных данных используйте серверный рендер или защищённый API с сессионной аутентификацией.
- Обратите внимание на GDPR: минимизируйте передачу личных данных и документируйте соглашение с третьими сторонами.
Короткий глоссарий (1 строка каждой термина)
- CSR — клиентский рендер: данные загружаются в браузере (useEffect).
- SSR — серверный рендер: страница генерируется при каждом запросе (getServerSideProps).
- SSG — статическая генерация: страница строится при сборке (getStaticProps).
- ISR — инкрементальная регенерация: статическая страница периодически обновляется (revalidate).
- SWR — клиентская библиотека кеширования и повторной валидации.
Шпаргалка / cheat sheet (короткие команды и опции)
- Установить SWR: npm install swr
- Отключить авто-рефетч при фокусе: revalidateOnFocus: false
- ISR: возвращать { props, revalidate: seconds } из getStaticProps
- Отмена fetch: const controller = new AbortController(); fetch(url, { signal: controller.signal })
Decision flow (мермейд) — упрощённое дерево выбора
flowchart TD
A[Нужен SEO?] -->|Да| B[Данные редко меняются?]
A -->|Нет| C[Персонализированные данные?]
B -->|Да| D[getStaticProps или ISR]
B -->|Нет| E[getServerSideProps]
C -->|Да| F[useEffect или SWR]
C -->|Нет| G[useEffect или SWR в зависимости от актуальности]Тест-кейсы / критерии приёмки (коротко)
- При отключённом JS (для страниц с getStaticProps/getServerSideProps) отображается основной контент.
- При медленном соединении компонент показывает индикатор «Загрузка» не дольше 5 секунд в локальной среде тестирования (ориентир).
- При сбое API пользователь получает понятное сообщение и кнопку «Повторить».
Резюме
Next.js предлагает набор инструментов для разных сценариев получения данных. Начните с понимания требований: SEO, частота обновлений, персонализация и нагрузка. Для клиентских сценариев используйте useEffect или SWR; для SEO и стабильного рендера — getStaticProps/getServerSideProps и ISR. Всегда обрабатывайте ошибки, отменяйте запросы при размонтировании и документируйте стратегию кэширования.
Important: планируйте критерии приёмки и тесты заранее, чтобы убедиться, что выбранная стратегия соответствует требованиям проекта.
Ключевые слова: useEffect, SWR, isomorphic-unfetch, getStaticProps, getServerSideProps, ISR
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone