В последнее время было много споров вокруг 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