--- title: Получение данных description: Как получать данные с учётом рендера страницы. keywords: [rest, стратегии, render, isr, ssr, server components, swr, promise, business] --- # Получение данных Как получать данные с учётом рендера страницы. Перед выбором стратегии должен быть настроен REST-клиент сервиса. Если клиента ещё нет, начните с раздела [Настройка REST-клиента](/docs/applied/rest-client/setup/). ## Сначала определите рендер страницы В 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](/docs/applied/data-fetch/server-await) | | Несколько независимых данных нужны до рендера | Запуск промисов + `Promise.all` | [Параллельные серверные запросы](/docs/applied/data-fetch/parallel-server-requests) | | Часть UI можно загрузить отдельно | Передача промиса ниже + `Suspense` | [Передача промиса ниже](/docs/applied/data-fetch/pass-promise-down) | | Client Component должен получить данные сразу из SWR | Начальные данные для клиентских хуков | [Начальные данные для клиентских хуков](/docs/applied/data-fetch/client-hooks-initial-data) | | Данные зависят от client state | Клиентский GET-хук | [Клиентский GET-хук](/docs/applied/data-fetch/client-get-hook) | | Нужно объединить несколько запросов или вычислить `isAuth`, `canEdit`, `hasPets` | Business-композиция | [Business-композиция](/docs/applied/data-fetch/business-composition) | ## Правило выбора Не выбирайте стратегию по любимому инструменту. Выбирайте её по двум вопросам: ```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/findByStatus?status=available'], () => petStoreApi.pet.findPetsByStatus({ status: StatusEnum.Available }), ) // Плохо — бизнес-флаг внутри GET-хука REST-клиента return { ...query, hasPets: Boolean(query.data?.length), } ``` Не отключайте ISR без причины. В компонентах используются готовые методы клиента или готовые хуки. SWR-ключи, fetcher и транспорт остаются внутри REST-модуля.