Быстрое обновление (Fast Refresh)
Быстрое обновление (Fast Refresh) — это функция Next.js, которая мгновенно отражает изменения в React-компонентах. Она включена по умолчанию во всех приложениях Next.js версии 9.4 и выше. С Fast Refresh большинство изменений отображаются в течение секунды, без потери состояния компонента.
Как это работает
- Если вы редактируете файл, который экспортирует только React-компонент(ы), Fast Refresh обновит код только для этого файла и перерендерит компонент. Вы можете изменять что угодно в файле: стили, логику рендеринга, обработчики событий или эффекты.
- Если вы редактируете файл с экспортами, которые не являются React-компонентами, Fast Refresh перезапустит этот файл и все файлы, которые его импортируют. Например, если и
Button.js
, иModal.js
импортируютtheme.js
, изменениеtheme.js
обновит оба компонента. - Если вы редактируете файл, который импортируется файлами вне React-дерева, Fast Refresh выполнит полную перезагрузку. Например, если ваш компонент экспортирует значение, которое импортируется не-React компонентом. В таком случае рекомендуется вынести константу в отдельный файл и импортировать её в оба файла. Это восстановит работу Fast Refresh. Другие случаи обычно решаются аналогично.
Устойчивость к ошибкам
Синтаксические ошибки
Если вы допустили синтаксическую ошибку, исправьте её и сохраните файл. Ошибка исчезнет автоматически без перезагрузки приложения. Состояние компонента не будет потеряно.
Ошибки времени выполнения
Если ошибка приводит к сбою во время выполнения, появится контекстное окно. Исправление ошибки автоматически закроет его без перезагрузки приложения.
Состояние компонента сохранится, если ошибка не произошла во время рендеринга. Если ошибка возникла при рендеринге, React перемонтирует приложение с обновлённым кодом.
Если в вашем приложении есть границы ошибок (error boundaries) (что рекомендуется для корректной работы в production), они повторят рендеринг после исправления ошибки. Это предотвратит сброс до корневого состояния приложения. Однако не делайте границы ошибок слишком мелкими — они используются React в production и должны быть продуманы.
Ограничения
Fast Refresh старается сохранять локальное состояние React в редактируемом компоненте, но только если это безопасно. Состояние может сбрасываться в следующих случаях:
- Состояние не сохраняется для классовых компонентов (только для функциональных компонентов и хуков).
- Файл может содержать другие экспорты помимо React-компонента.
- Если файл экспортирует результат вызова компонента высшего порядка (HOC), например
HOC(WrappedComponent)
, и возвращаемый компонент является классом, его состояние сбросится. - Анонимные стрелочные функции, например
export default () => <div />;
, не сохраняют состояние. Для больших проектов можно использовать codemodname-default-component
.
Чем больше кода использует функциональные компоненты и хуки, тем чаще состояние будет сохраняться.
Советы
- Fast Refresh сохраняет локальное состояние функциональных компонентов (и хуков) по умолчанию.
- Чтобы принудительно сбросить состояние и перемонтировать компонент (например, для анимации при монтировании), добавьте
// @refresh reset
в файл. Эта директива действует только в текущем файле. - Можно использовать
console.log
илиdebugger;
в компонентах во время разработки. - Импорты чувствительны к регистру. Ошибки в регистре (например,
'./header'
вместо'./Header'
) могут привести к сбою Fast Refresh.
Fast Refresh и хуки
Fast Refresh сохраняет состояние хуков useState
и useRef
, если не меняются их аргументы или порядок вызова.
Хуки с зависимостями (useEffect
, useMemo
, useCallback
) всегда обновляются при Fast Refresh. Их зависимости игнорируются во время обновления.
Например, при изменении useMemo(() => x * 2, [x])
на useMemo(() => x * 10, [x])
хук перезапустится, даже если x
не изменился. Без этого изменения не отобразятся на экране!
Иногда это приводит к неожиданным результатам. Например, useEffect
с пустым массивом зависимостей всё равно выполнится один раз при Fast Refresh.
Однако писать код, устойчивый к повторному выполнению useEffect
, — хорошая практика даже без Fast Refresh. Это упрощает добавление новых зависимостей и соответствует React Strict Mode, который рекомендуется включать.