Сравнение загрузки страниц в 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 может повторить этот подход, обеспечивая гибкость для серверной и клиентской логики.

Оглавление

Что такое загрузка страниц в веб-фреймворках

Загрузка страниц — это процесс получения данных из 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) хранят состояние.
  • Отсутствие useEffect Server 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)
Гибкость Фокус на серверо-ориентированности Высокая гибкость (серверные и клиентские опции) Гибкий, но требует больше ручного управления

Основные моменты

  1. Использование Server Components в Next.js Загружайте данные в app/feed/page.tsx и используйте <Link> для навигации.
  2. Хранение состояния в URL Параметры запроса (?tag=react) упрощают управление состоянием.
  3. Оптимизация производительности В Remix используется defer, в Next.js — Suspense и кэширование fetch.

Заключение

Remix упрощает загрузку страниц с помощью loader и состояния в URL, исключая useState и useEffect. В Next.js можно воспроизвести этот подход через Server Components . Оба фреймворка минимизируют клиентскую сложность, делая их подходящими для современных веб-приложений.

Один ответ к «Сравнение загрузки страниц в Remix и Next.js»

  1. Это сделать просто, если иметь промокод Mostbet на сегодня бесплатно. Правда, дается он при условии выполнения некоторых правил. casino промокод. Не совсем промокод, но вы все равно ставите не свои деньги, если пополните депозит, – 100% бонуса от внесенной суммы. Максимум указан в верхней части главной страницы официального сайта. 100% бонус за пополнение от Mostbet. Но прежде чем получить бонус нужно пройти регистрацию. Зайдите на сайт БК Mostbet и нажмите по стрелке кнопку «Регистрация». 2. Выберите один из методов регистрации (самый быстрый — в один клик). Кликните на «Зарегистрироваться».

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

*