Сравнение загрузки страниц в Remix и Next.js
Изучая документацию по FSD, я обнаружил пример по Remix демонстрирующий очень простой подход к загрузке страницы. И решил воспроизвести этот подход в Next.js.
Сравнение загрузки страниц в Remix и Next.js
Remix и Next.js — два SSR JavaScript-фреймворка, предлагающих разные подходы к загрузке страниц. Remix использует серверную логику и URL для управления состоянием, исключая необходимость в React-хуках useState и useEffect. Next.js с App Router и Server Components может повторить этот подход, обеспечивая гибкость для серверной и клиентской логики.
Оглавление
- Что такое загрузка страниц в веб-фреймворках
- Загрузка страниц в Remix
- Воспроизведение подхода Remix в Next.js
- Когда в Next.js появляется useEffect
- Таблица сравнения Remix против Next.js
- Основные моменты
- Заключение
Что такое загрузка страниц в веб-фреймворках
Загрузка страниц — это процесс получения данных из API или базы данных и их отображения на веб-странице. В традиционных React-приложениях используются useState для управления данными и useEffect для их загрузки при монтировании компонента или изменении параметров, что может усложнять код из-за управления побочными эффектами и синхронизации состояния.
Remix упрощает процесс, перенося загрузку данных на сервер и используя параметры URL как источник состояния, что устраняет необходимость в клиентских хуках. Next.js с App Router и Server Components также поддерживает этот подход, но позволяет использовать и клиентскую загрузку данных, где хуки могут быть нужны.
Загрузка страниц в Remix
Ключевые особенности
- Серверные функции
loaderКаждый маршрут может экспортировать функциюloader, выполняющуюся на сервере для получения данных. Она автоматически вызывается при доступе к маршруту или изменении URL. - URL как состояние Параметры запроса (например,
?tag=react) хранят состояние, устраняя необходимость вuseState. - Отсутствие
useEffectЗагрузка данных происходит на сервере, что исключает необходимость в клиентских побочных эффектах.
Пример Фильтрация статей по тегам
Рассмотрим пример фильтрации статей по тегам (например, “react” или “javascript”) с использованием RealWorld API, без useState и useEffect.
Серверная функция loader
Функция loader получает статьи и теги, фильтруя по параметру tag.
// pages/feed/api/loader.ts
import { json, type LoaderFunctionArgs } from "@remix-run/node";
import { promiseHash } from "remix-utils/promise";
import { GET } from "shared/api";
async function throwAnyErrors(
responsePromise: Promise>,
) {
const { data, error, response } = await responsePromise;
if (error !== undefined) {
throw json(error, { status: response.status });
}
return data as NonNullable;
}
export const loader = async ({ request }: LoaderFunctionArgs) => {
const url = new URL(request.url);
const selectedTag = url.searchParams.get("tag") ?? undefined;
return json(
await promiseHash({
articles: throwAnyErrors(
GET("/articles", { params: { query: { tag: selectedTag } } })
),
tags: throwAnyErrors(GET("/tags")),
})
);
};
Код читает параметр tag из URL, запрашивает отфильтрованные статьи и теги, возвращая данные в JSON.
Клиентский компонент
Компонент FeedPage отображает статьи и теги, используя форму для обновления URL.
Компонент использует useLoaderData для доступа к данным и рендерит статьи и теги в виде кнопок в форме <Form>.
Конфигурация маршрута
Маршрут связывает loader и компонент FeedPage для маршрута /.
Почему нет useState или useEffect
- Нет
useStateТег хранится в URL (?tag=react). - Нет
useEffectЗагрузка данных происходит вloaderна сервере.
Воспроизведение подхода Remix в Next.js
Ключевые особенности
- Server Components Выполняются на сервере, загружая данные и рендеря HTML без клиентского JavaScript.
- URL как состояние Параметры запроса (
?tag=react) хранят состояние. - Отсутствие
useEffectServer Components загружают данные во время рендеринга. - Мягкая навигация Поддерживается через
<Link>, обновляя URL без перезагрузки.
Пример Фильтрация статей по тегам
Серверная загрузка данных
// lib/api.ts
export async function getArticles(tag?: string) {
const response = await fetch(
`https://api.realworld.io/api/articles${tag ? `?tag=${tag}` : ""}`,
{ cache: "force-cache" }
);
if (!response.ok) throw new Error("Не удалось загрузить статьи");
return response.json();
}
export async function getTags() {
const response = await fetch("https://api.realworld.io/api/tags", {
cache: "force-cache",
});
if (!response.ok) throw new Error("Не удалось загрузить теги");
return response.json();
}
Функции запрашивают статьи и теги, используя кэширование для оптимизации.
Server Component
Компонент загружает данные на сервере и рендерит интерфейс с тегами в виде <Link>.
Компонент ArticlePreview
Почему нет useState или useEffect
- Нет
useStateТег хранится в URL. - Нет
useEffectДанные загружаются на сервере.
Улучшение с помощью Server Actions
Для имитации поведения <Form> в Remix можно использовать Server Actions.
Server Action перенаправляет на новый URL, вызывая перерендеринг без useEffect.
Когда в Next.js появляется useEffect
В Client Components ("use client") useEffect нужен для динамической загрузки данных.
useEffect отслеживает изменения searchParams и загружает данные. Server Components позволяют избежать этого.
Таблица сравнения Remix против Next.js
Сравнение удобства загрузки страниц в Remix и Next.js.
| Аспект | Remix | Next.js (Server Components) | Next.js (Client Component) |
|---|---|---|---|
Устранение useEffect |
Да, через loader и useLoaderData |
Да, через Server Components | Нет, требуется useEffect для загрузки данных |
Устранение useState |
Да, состояние в URL | Да, состояние в URL | Да, состояние в URL, но useState для данных |
| Навигация | Мягкая (SPA), loader вызывается автоматически |
Мягкая (SPA), Server Component перерендеривается | Мягкая (SPA), useEffect для повторных запросов |
| Интеграция форм | Декларативная (<Form> вызывает loader/action) |
Требует Server Actions и redirect |
Требует useEffect или клиентской логики |
| Кэширование | Встроенное, через Cache-Control |
Автоматическое, через fetch/revalidate |
Ручное (через fetch или состояние) |
| Поведение без JS | Работает (формы отправляются как HTML) | Ограниченно (формы требуют Server Actions) | Не работает (требуется JS для useEffect) |
| Гибкость | Фокус на серверо-ориентированности | Высокая гибкость (серверные и клиентские опции) | Гибкий, но требует больше ручного управления |
Основные моменты
- Использование Server Components в Next.js Загружайте данные в
app/feed/page.tsxи используйте<Link>для навигации. - Хранение состояния в URL Параметры запроса (
?tag=react) упрощают управление состоянием. - Оптимизация производительности В Remix используется
defer, в Next.js —Suspenseи кэшированиеfetch.
Заключение
Remix упрощает загрузку страниц с помощью loader и состояния в URL, исключая useState и useEffect. В Next.js можно воспроизвести этот подход через Server Components . Оба фреймворка минимизируют клиентскую сложность, делая их подходящими для современных веб-приложений.
Это сделать просто, если иметь промокод Mostbet на сегодня бесплатно. Правда, дается он при условии выполнения некоторых правил. casino промокод. Не совсем промокод, но вы все равно ставите не свои деньги, если пополните депозит, – 100% бонуса от внесенной суммы. Максимум указан в верхней части главной страницы официального сайта. 100% бонус за пополнение от Mostbet. Но прежде чем получить бонус нужно пройти регистрацию. Зайдите на сайт БК Mostbet и нажмите по стрелке кнопку «Регистрация». 2. Выберите один из методов регистрации (самый быстрый — в один клик). Кликните на «Зарегистрироваться».