12 - Next.js и React: Хук use, Suspense и loading.js | Правильная загрузка данных

Для доступа к видео войдите в систему

12 - Next.js и React: Хук use, Suspense и loading.js | Правильная загрузка данных

Оценить качество материала и подачу материала автором видео:

Front-end

Трудоустройтесь middle front-end разработчиком на React JS (TypeScript) за 12-16 месяцев обучения с ежедневной менторской поддержкой в формате видео 1 на 1 и коммерческими проектами в портфолио

Перейти на курс
Front-end

Back-end

Трудоустройтесь middle back-end разработчиком за 12-16 месяцев обучения с ежедневной менторской поддержкой в формате видео 1 на 1 и коммерческими проектами в портфолио

Перейти на курс
Back-end

Карьерный бустер

Получите коммерческий опыт на реальных стартапах, прокачайте tech & soft навыки, научитесь работать в команде, проходить собеседования и получите первую работу в IT!

Перейти на курс
Карьерный бустер

Основы Front-end

Сделайте первый шаг в IT, освоив базовые знания разработки и научившись создавать небольшие проекты на JavaScript

Перейти на курс
Основы Front-end

Основы Back-end

Сделайте первый шаг в IT, освоив базовые знания разработки. Без опыта. Без математики. Только практика: JavaScript, SQL, Node JS, база данных

Перейти на курс
Основы Back-end

React hook use with Suspense and file loading

Автор конспекта: Стогниева Виктория

1️⃣ Введение: проблема получения данных в клиентских компонентах Next.js

Одна из ключевых задач при разработке современных приложений на Next.jsэффективное получение данных на стороне клиента, при этом с максимальным использованием возможностей серверных компонентов ⚙️

От выбранной стратегии напрямую зависят:

  • ⚡ производительность,
  • 🧠 интерактивность интерфейса,
  • 🔍 SEO-дружественность приложения в архитектуре App Router.

Грамотно выстроенный подход позволяет создавать быстрые, отзывчивые и хорошо индексируемые веб-приложения. В рамках этой лекции рассматриваются два фундаментальных подхода, каждый из которых решает задачу получения данных по-своему и применяется в разных сценариях.

2️⃣ Стратегия 1: передача готовых данных с сервера

Server-Side Resolution 🖥️

Данный подход — классический и наиболее надёжный способ доставки контента, который должен быть доступен сразу как пользователям, так и поисковым роботам 🤖

Его ключевая ценность заключается в том, что все асинхронные операции полностью завершаются на сервере, прежде чем HTML будет отправлен в браузер.

2.1 🔄 Механизм работы

Процесс реализации этой стратегии логичен и последователен и включает три основных шага:

1️⃣ Запрос данных в серверном компоненте Асинхронный запрос выполняется непосредственно в серверном компоненте страницы.

2️⃣ Ожидание результата Сервер дожидается полного выполнения асинхронной операции и получает готовые данные.

3️⃣ Передача данных в клиентский компонент Уже подготовленные данные передаются в клиентский компонент через props.

📌 В результате клиентский компонент получает не Promise, а полностью готовый набор данных.

2.2 🔍 Анализ результата и влияние на SEO

При использовании этой стратегии HTML, который сервер отправляет браузеру, уже содержит все данные 📄

Это означает:

  • 🔎 поисковые роботы видят контент сразу,
  • 📡 отсутствуют дополнительные клиентские запросы,
  • 🚀 улучшается производительность первой загрузки.

💡 Вывод Этот подход идеально подходит для страниц, где:

  • важна SEO-индексация,
  • критична скорость первой отрисовки,
  • контент является публичным.

Однако иногда важнее как можно быстрее показать пользователю интерактивный каркас, а данные загрузить позже. Для этого существует альтернативная стратегия.

3️⃣ Стратегия 2: передача Promise и использование use

Client-Side Resolution 🧩

В этой стратегии меняется сама парадигма: сервер не ждёт данные, а отправляет HTML сразу, передавая обещание (Promise), что данные будут получены позже ⏳

Этот подход тесно связан с:

  • 🌀 архитектурой Suspense,
  • 🧠 новым хуком use.
page.tsx
import styles from '../page.module.css';
import { Metadata } from 'next';
import { Suspense } from 'react';
 
export const metadata: Metadata = {
  title: "Books page",
  description: "Generated by create next app books page",
};
 
const getTodolists = async (): Promise<{ title: string }[]> => {
  const data = await fetch('https://jsonplaceholder.typicode.com/todos')
  return data.json()
}
 
export default async function Books() {
  const todolists = await getTodolists()
 
  return (
    <div className={styles.page}>
      <main className={styles.main}>
        <Suspense fallback={<div>Loading...</div>}>
          <Todolists todolists={todolists} />
        </Suspense>
      </main>
    </div>
  )
}
Todolists.tsx
'use client'
 
import {use} from 'react'
 
type Props = {
  todolists: Promise<{ title: string }[]>
}
 
export const Todolists = async ({ todolists }: Props) => {
  const todos = use(todolists)
 
  return (
    <div>
      <div>Todolists</div>
      {todos.map(todo => (
        <div key={todo.title}>{todo.title}</div>
      ))}
    </div>
  )
}

3.1 🧠 Концепция: передача Promise в качестве props

Ключевое отличие стратегии — клиентский компонент получает не данные, а незавершённый Promise.

📌 Это требует:

  • корректной типизации,
  • понимания того, что сервер и клиент теперь живут в разных временных циклах.

💡 Сервер может отправить HTML до завершения запроса к API или базе данных, не блокируя рендеринг страницы.

3.2 📦 Реализация: хук use для «распаковки» Promise

Для работы с Promise внутри клиентского компонента используется хук use.

🔹 Его поведение:

  • рендеринг компонента приостанавливается,
  • выполнение продолжается только после разрешения Promise,
  • в итоге компонент получает готовые данные.

⚠️ Именно эта «пауза» делает обязательным использование Suspense.

🧠 Важно знать: Хук use также может использоваться для получения значений из React Context, что делает его универсальным инструментом нового поколения.

3.3 ⏳ Интеграция с Suspense: управление загрузкой

Использование use с Promise невозможно без границы Suspense.

🎭 Роль Suspense:

  • перехватывает состояние ожидания,
  • отображает временный интерфейс загрузки,
  • обеспечивает предсказуемый UX.

📌 Пока данные загружаются, пользователь видит fallback-интерфейс, а не пустой экран.

3.4 🔍 Анализ результата и влияние на SEO

Последствия этой стратегии принципиально отличаются от первой:

  • 📄 В исходном HTML содержится только fallback
  • 🔍 Поисковые роботы не видят финальный контент
  • ⏱️ Данные подгружаются уже на клиенте

💡 Вывод Подход идеально подходит для контента, который:

  • не требует SEO-индексации,
  • является персональным или динамическим.

📊 Примеры:

  • личные кабинеты,
  • дашборды,
  • пользовательские настройки.

4️⃣ Управление загрузкой на уровне страницы

Файл loading.tsx 🧱

Next.js расширяет концепцию Suspense, позволяя управлять загрузкой на уровне маршрута.

loading.tsx
export  default function Loading(){
  return <div>Loading...</div>
}

4.1 ⚙️ Назначение и принцип работы

Файл loading.tsx — специальный механизм маршрутизации Next.js.

📌 Его особенности:

  • автоматически оборачивает страницу в Suspense,
  • используется как fallback-интерфейс,
  • срабатывает при навигации между страницами.

Преимущество для UX Пользователь сразу видит:

  • общий layout,
  • навигацию,
  • каркас страницы, пока основной контент загружается.

4.2 ⚖️ Сравнение с ручным использованием Suspense

Выбор зависит от масштаба задачи:

  • 🧱 loading.tsxИспользуется для отображения загрузки всей страницы или маршрута.

  • 🧩 Suspense Подходит для точечного контроля загрузки отдельных блоков интерфейса.

📌 Оба подхода могут эффективно сочетаться в одном приложении.

5️⃣ Сравнительный анализ и ключевые выводы

Выбор стратегии — это не вопрос «лучше или хуже», а осознанный компромисс между:

  • SEO 📈,
  • скоростью первой загрузки ⚡,
  • воспринимаемой производительностью 🧠.