Skip to content

Стратегии получения данных

Как выбрать получение REST-данных с учётом рендера страницы.

Перед выбором стратегии должен быть создан REST-клиент сервиса. Если клиента ещё нет, начните с раздела Создание клиента.

Сначала определите рендер страницы

В Next.js выбор начинается не с await, Suspense или SWR. Сначала нужно понять, какой рендер получится у маршрута: static/ISR или dynamic/SSR.

Next.js может перевести страницу в dynamic rendering автоматически, если в маршруте используются API текущего запроса. Поэтому первый вопрос такой:

text
Можно ли сохранить ISR, или странице нужны данные на каждый request?

ISR — приоритет. Если данные общие для пользователей и их можно обновлять с интервалом, не переводите страницу в SSR без необходимости.

SSR/dynamic rendering выбирается только когда данные действительно зависят от текущего request или должны пересчитываться на каждый запрос.

Что переводит страницу в dynamic rendering

Проверьте, нужны ли странице API и настройки, которые делают маршрут динамическим:

  • cookies() — данные зависят от cookie текущего пользователя.
  • headers() — данные зависят от request headers.
  • draftMode() — нужен preview/draft-режим.
  • searchParams в page.tsx — данные зависят от query string.
  • cache: 'no-store' или revalidate: 0 в методе клиента — запрос нельзя кешировать.
  • connection() — рендер явно ждёт request.
  • export const dynamic = 'force-dynamic' — SSR включён вручную.

Если ничего из этого не нужно, сначала проектируйте страницу как static/ISR. Серверный await сам по себе не означает SSR: режим зависит от кеширования запроса и dynamic API маршрута.

Рендер перед стратегией

РендерКогда подходитЧто выбирать дальше
Static/ISRДанные общие и могут обновляться по интервалуСерверные стратегии: await, Promise.all, передача промиса ниже, SWR fallback
SSR/dynamicДанные зависят от request, пользователя или должны быть свежими на каждый запросСерверные стратегии с учётом блокировки первого HTML
После гидрацииДанные зависят от вкладки, фильтра, поиска, пагинации или действия пользователяКлиентский GET-хук

Как выбрать стратегию

Когда режим рендера понятен, выбирайте конкретный способ получения данных:

Ситуация после выбора рендераСтратегияГде читать
Данные обязательны для первого HTML, SEO, notFound() или redirect()Серверный awaitСерверный await
Несколько независимых данных нужны до рендераЗапуск промисов + Promise.allПараллельные серверные запросы
Часть UI можно загрузить отдельноПередача промиса ниже + SuspenseПередача промиса ниже
Client Component должен получить данные сразу из SWRНачальные данные для клиентских хуковНачальные данные для клиентских хуков
Данные зависят от client stateКлиентский GET-хукКлиентский GET-хук
Нужно объединить несколько запросов или вычислить isAuth, canEdit, hasPetsBusiness-композицияBusiness-композиция

Правило выбора

Не выбирайте стратегию по любимому инструменту. Выбирайте её по двум вопросам:

text
Можно ли сохранить ISR?
Где нужны данные и что должно произойти до первого HTML?

Если данные можно кешировать между пользователями — сохраняйте static/ISR. Если данные request-specific — используйте SSR/dynamic rendering. Если данные зависят от состояния браузера — используйте GET-хук REST-клиента. Если простой GET превращается в доменный сценарий — переходите в business/.

Общие запреты

tsx
// Плохо — SSR включён на всякий случай
export const dynamic = 'force-dynamic'

// Плохо — ISR отключён без требования к свежести на каждый request
export const revalidate = 0

// Плохо — прямой fetch в компоненте
useEffect(() => {
  fetch('/api/pets').then(...)
}, [])

// Плохо — useSWR в компоненте
const { data } = useSWR(
  ['pet-store-api', 'pet', 'list', status],
  () => petStoreApi.pet.findPetsByStatus({ status }),
)

// Плохо — бизнес-флаг внутри GET-хука REST-клиента
return {
  ...query,
  hasPets: Boolean(query.data?.length),
}

Не отключайте ISR без причины. В компонентах используются готовые методы клиента или готовые хуки. SWR-ключи, fetcher и транспорт остаются внутри REST-модуля.