ПРАКТИЧЕСКИЙ РАЗБОР · 7 минут

React или Next.js. Когда стоит переходить на Next.js

Когда React-приложению нужен Next.js, что меняется в маршрутизации, серверной загрузке данных и компонентах, как начать переход

Вы уже пишете приложения на React. Умеете создавать компоненты, работать с useState, подключать API и настраивать маршруты. Для небольшого проекта этого достаточно. Но со временем появляются новые задачи. Нужно показывать страницы товаров по отдельным адресам, получать данные на сервере, управлять метаданными и публиковать сайт без сложной ручной настройки.

Возникает вопрос, продолжать развивать React-приложение с выбранными библиотеками или перейти на Next.js. Разберём различия на примере каталога товаров и определим, когда переход имеет смысл.

Next.js не заменяет React

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

Next.js, фреймворк, построенный на React. В нём вы продолжаете писать React-компоненты, но получаете готовую систему маршрутов, серверного рендеринга, загрузки данных и сборки приложения.

Поэтому сравнение не совсем похоже на выбор двух независимых технологий. Вопрос скорее в том, нужна ли вашему React-проекту структура и серверные возможности, которые предоставляет Next.js. Если вы делаете небольшое браузерное приложение, где пользователь открывает одну страницу и работает с локальными данными, React вместе с Vite может полностью решать задачу. Переход на Next.js только ради другого названия технологии не требуется.

Когда обычного клиентского приложения достаточно

Представим внутреннюю панель управления. Пользователь входит в систему, открывает таблицы и редактирует записи. Почти все данные поступают из защищённого API, а поисковые системы не должны индексировать страницы кабинета. Такое приложение можно построить на React с клиентской маршрутизацией. Для работы с формами, запросами и состоянием при необходимости добавляются библиотеки. Сама по себе их установка не означает, что архитектура неправильная.

Другой пример интерактивный инструмент, который выполняет расчёты в браузере и не нуждается в серверной загрузке страниц. Здесь Next.js может добавить новые понятия без заметной пользы для задачи. Переход оправдан, когда появляются требования, которые удобнее решать средствами фреймворка, а не отдельными настройками.

Что меняется в маршрутизации

В обычном React-приложении маршруты часто описывают через отдельную библиотеку. В Next.js App Router адреса определяются структурой папок. Например, файл app/catalog/page.tsx соответствует странице /catalog, а app/catalog/[id]/page.tsx странице конкретного товара с динамическим параметром.

Можно создавать общие макеты через layout.tsx, вложенные маршруты и отдельные состояния загрузки. Это помогает организовать приложение, в котором много взаимосвязанных страниц. Но готовая маршрутизация не отменяет проектирование. Названия URL, вложенность разделов и поведение переходов всё равно придётся продумать.

Как выглядит первая страница в Next.js

Для небольшого примера создадим страницу каталога в App Router.

// app/catalog/page.tsx

const products = [
  { id: 1, name: "Кофе" },
  { id: 2, name: "Чай" },
];

export default function CatalogPage() {
  return (
    <main>
      <h1>Каталог</h1>

      <ul>
        {products.map((product) => (
          <li key={product.id}>{product.name}</li>
        ))}
      </ul>
    </main>
  );
}

Здесь обычный React-компонент становится страницей по адресу /catalog благодаря расположению файла. Для такого статического примера не требуется useState или клиентский JavaScript для вычисления списка.

В Next.js App Router страницы и макеты по умолчанию являются серверными компонентами. Это позволяет получать данные и подготавливать интерфейс на сервере. Но не все компоненты нужно делать серверными. Интерактивные части продолжают работать в браузере.

Где остаются useState и обработчики событий

Предположим, у каждой карточки товара появилась кнопка «В избранное». Она меняет состояние после нажатия. Для такой задачи нужен клиентский компонент с директивой "use client".

"use client";

import { useState } from "react";

export default function FavoriteButton() {
  const [saved, setSaved] = useState(false);

  return (
    <button
      type="button"
      aria-pressed={saved}
      onClick={() => setSaved((value) => !value)}
    >
      {saved ? "В избранном" : "В избранное"}
    </button>
  );
}

Такой компонент можно использовать внутри серверной страницы каталога. Он отвечает за нажатие и изменение интерфейса, а страница за получение и отображение данных. Это один из подходов Next.js. Не обязательно переводить весь сайт в клиентский режим ради одной интерактивной кнопки. При этом локальное состояние из примера исчезнет после полной перезагрузки. Для постоянного избранного потребуется отдельное хранилище.

Механика состояния разобрана в статье «Как работает useState в React на примере избранных товаров».

Что даёт серверная загрузка данных

В клиентском React-приложении данные часто загружаются после открытия страницы в браузере. Интерфейс сначала показывает оболочку или индикатор загрузки, затем получает ответ API.

В Next.js серверный компонент может выполнить запрос до передачи готового интерфейса браузеру. Это подходит для каталога, статьи или страницы товара, где содержимое связано с адресом. Но Next.js не делает любой запрос автоматически быстрее. Результат зависит от источника данных, времени ответа сервера, настроек кэширования и способа рендеринга. Серверные запросы также требуют обработки ошибок. Для приложений с публичными страницами это даёт больше возможностей управлять тем, какой HTML получает посетитель и поисковый робот.

А что насчёт SEO

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

Next.js предоставляет инструменты для генерации метаданных, sitemap и серверного рендеринга. Это удобно, когда товары, статьи и другие публичные страницы должны иметь собственные адреса и содержимое. При этом использование Next.js само по себе не гарантирует позиции в поиске. Нужно отдельно выбирать, какие страницы индексировать, как связывать их между собой и какие данные показывать.

Для внутренних панелей, закрытых личных кабинетов и инструментов без публичных страниц SEO обычно не является причиной менять фреймворк.

Нужно ли переписывать существующий проект

Не обязательно переносить всё приложение сразу. Начните с небольшой самостоятельной страницы и проверьте, как в Next.js организованы маршруты, данные и интерактивные компоненты. Знакомые React-компоненты часто можно использовать повторно. Но код, который обращается к window, localStorage или событиям браузера, требует внимания к границе между сервером и клиентом.

Также предстоит пересмотреть маршрутизацию, переменные окружения и способы загрузки данных. Если проект уже стабильно работает на React с Vite, стоимость перехода нужно сравнить с ожидаемыми преимуществами. Официальная инструкция Next.js по миграции с React-приложения описывает подход к переносу существующего проекта с Vite.

От React-компонентов к приложению на Next.js

В моей статье на Habr о Route Handlers показано, как внутри Next.js появляется серверная часть для работы с запросами. Это один из вариантов развития приложения, которому уже недостаточно только клиентского интерфейса.

В Goods Finder можно посмотреть каталог на Next.js с маршрутизацией, поиском и пользовательскими действиями.

Курс «Next.js I: JavaScript 2026» рассчитан на переход от знакомых принципов JavaScript и React к App Router, загрузке данных, URL-фильтрам и деплою приложения.

Выбирайте Next.js не потому, что React перестал справляться с компонентами. Переход имеет смысл, когда проекту нужны встроенные маршруты, серверная работа с данными и управление публичными страницами. Для небольшого клиентского приложения React с привычными инструментами может оставаться достаточным решением.