В последнее время было много споров вокруг NextJS 13, в частности, большой гнев сообщества был направлен на App Router. Я хотел изучить это разочарование и поделиться некоторыми своими взглядами.

Кэшируется по умолчанию

В недавнем видео Josh Tried Coding (кстати, отличный канал — поставьте лайк и подпишитесь) он исследует поведение кэширования NextJS 13 на простом примере. Вот разбор кода для удобства

import Link from 'next/link';

export default function IndexPage() {
  return <main>
    {Math.random()}
    <Link href="/away">Navigate Away</Link>
  </main>

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

Честно говоря, как разработчик JavaScript, это разумное предположение. У нас есть в интерполированных фигурных скобках JavaScript вызов метода Math.random, который теоретически должен предоставлять нам новое число при каждом запросе страницы. Однако это неправильное понимание того, как работает NextJS 13 и как он должен себя вести.

Сервер визуализируется (и кэшируется) по умолчанию

На изображении выше мы видим, как NextJS кэширует запросы. Это делается с двух сторон; клиент и сервер. В видео Джош довольно хорошо описывает, как такое поведение предназначено для дедупликации запросов, и продолжает иллюстрировать, как можно отключить аспекты кэширования на стороне сервера.

К его большому разочарованию и некоторым комментаторам, NextJS не позволяет нам обойти кэширование маршрутизатора на стороне клиента. Как указано в разделе «Отказ от участия» их документов.

Для полного понимания того, как работает кэширование в NextJS, я рекомендую прочитать документацию и посмотреть видео Джоша.

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

Решение на виду

Как было сказано ранее, я считаю, что это разочарование неуместно. Команда NextJS совершенно ясно представляет, как должны использоваться RSC (серверные компоненты React). Реактивность, интерактивность и динамизм должны быть вытеснены из наших приложений. Когда в документации говорится «интерактивный пользовательский интерфейс», важно учитывать всю полноту интерактивности.

Взаимодействие не ограничивается входными данными с устройства пользователя, такими как ввод текста или клики, но также и JavaScript, который взаимодействует с нашей веб-страницей. Идиоматическое решение проблемы, представленной в видео Джоша, такое…

"use client";

import React from "react";

export function Random() {
  const [state] = React.useState<number>(Math.random());
  return <h1>{state}</h1>;
}

В приведенном выше примере у нас есть простой клиентский компонент, который отображает случайно сгенерированное число. Этот компонент можно использовать на нашей индексной странице следующим образом…

import Link from "next/link";
import { Random } from "./random";

export default function IndexPage() {
  return (
    <main>
      <article>
        <h2>
          Unchanging - <span>{Math.random()}</span>
        </h2>
        <Random /> {/* 👈 Our Random Component */}
        <Link href="/before">Navigate Away ⏩</Link>
      </article>
    </main>
  );
}

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

В заключение отметим, что команда NextJS в Vercel проделала большую работу, справившись с спорным и сложным запуском Next 13. Серверные компоненты React подталкивают нас к более тонкому и тонкому рендерингу, который со временем проявит себя все больше.

✨ Посмотреть пример репозитория можно здесь: https://github.com/warren-sadler/nextjs-caching

Рекомендации