React 19.3: анимации переходов и browser() вышли из эксперимента

9 сентября 2026 года команда React выпустила версию 19.3. Анимации переходов `<ViewTransition>` и ссылки на фрагменты (Fragment Refs), которые с апреля 2025 года были экспериментальными, стали стабильными. Появились API `browser()` для компонентов, которые работают только в браузере, и поддержка Trusted Types. 6 октября React 19.3 вошёл в Next.js 16.4. Новость касается всех проектов на React и Next.js.
Что нового
ViewTransition. Компонент анимирует появление, исчезновение, перемещение и изменение размеров элементов через браузерный View Transition API. Анимация срабатывает только для обновлений, помеченных как переход: `startTransition`, раскрытие Suspense или `useDeferredValue`. По умолчанию — плавное перекрёстное затухание, его можно заменить своими CSS-классами.
Функция `addTransitionType` позволяет одному и тому же изменению анимироваться по-разному в зависимости от причины: например, листание слайдов вперёд и назад. Тип перехода доступен и в CSS.
Fragment Refs. Ссылку теперь можно повесить на `<Fragment>` и работать с дочерними элементами группой: вешать обработчики событий, управлять фокусом, подключать IntersectionObserver и ResizeObserver, прокручивать к элементу. Без лишней обёртки-div — и даже для компонентов из библиотек, которые не пробрасывают ref.
browser(). Компонент с `use(browser())` не рендерится на сервере: в HTML попадает ближайший fallback из Suspense, а в браузере компонент работает как обычно. Это замена самодельным флагам «смонтирован ли компонент» и проверкам `typeof window`, которые часто ломали гидрацию.
Trusted Types. Если сайт включил политику `require-trusted-types-for 'script'`, React больше не превращает объекты TrustedHTML в строки. Раньше браузер такие строки отклонял, и политику безопасности приходилось ослаблять.
Контекст в серверных компонентах. Серверный компонент может рендерить контекст из клиентского модуля напрямую, без обёртки-провайдера.

Было и стало
| Задача | Раньше | В React 19.3 |
|---|---|---|
| Анимация перехода между состояниями | Сторонние библиотеки или эксперимент | Стабильный ViewTransition |
| Ref на группу элементов | Лишний div-обёртка | Ref на Fragment |
| Компонент только для браузера | useEffect с флагом, typeof window | use(browser()) |
| CSP с Trusted Types | Приходилось ослаблять | Работает без обходов |
| Медленный переход блокирует другие | Да | Переходы рендерятся независимо |
Что может измениться в поведении
Ломающих изменений в анонсе нет, но в журнале изменений есть поведенческие:
- переходы рендерятся независимо — медленный переход больше не задерживает остальные;
- в Strict Mode при гидрации эффекты вызываются дважды, как и при клиентском рендеринге — в режиме разработки могут проявиться эффекты без корректной очистки;
- обновления от события resize группируются до следующего кадра;
- `use` предупреждает при условном вызове;
- в сообщениях об ошибках `useActionState` «form state» заменено на «action state».
Исправлены и давние ошибки: зависание `useDeferredValue` на старом значении, пропуск изменений хранилища в `useSyncExternalStore` внутри скрытого `<Activity>`, падения Mobile Safari вместе с `<ViewTransition>`.
Что увидит пользователь
Для посетителя сайта изменения React 19.3 выглядят так. Переход из каталога в карточку товара может плавно «перелетать» картинкой, а не мигать белым экраном. При загрузке данных вместо резкой подмены заглушки на контент — короткая анимация. Картинки и шрифты внутри ViewTransition ждут загрузки вместе с данными, поэтому блок не «прыгает», когда шрифт догрузился.
Всё это и раньше делалось сторонними библиотеками, но ценой лишних десятков килобайт JavaScript и хрупкой логики. Теперь это штатная возможность, которая опирается на браузерный API. В браузерах без поддержки View Transition API обновление просто применяется без анимации — сайт не ломается.
Ещё один заметный эффект — меньше ошибок гидрации. Когда компонент читает localStorage или часовой пояс на сервере, где их нет, HTML с сервера не совпадает с тем, что рисует браузер, и React ругается или перерисовывает страницу. `browser()` решает это штатно.
Совместимость с библиотеками
React 19.3 — минорная версия, поэтому библиотеки, работающие с 19.x, как правило, продолжают работать. Риски — у библиотек, которые полагаются на порядок эффектов в Strict Mode или на синхронную обработку resize. Перед обновлением проверьте раздел issues у ключевых зависимостей: UI-кита, роутера, форм, графиков.
Кого касается
- проектов на Next.js 16.4 — React 19.3 уже внутри;
- приложений с анимациями интерфейса и сложной навигацией;
- сайтов со строгой политикой безопасности контента (CSP);
- компонентов, которые читают localStorage, часовой пояс или размер окна.
Что делать
- Обновите React и react-dom до 19.3 в отдельной ветке и прогоните тесты.
- Запустите приложение в режиме разработки со Strict Mode: если эффекты ломаются при двойном вызове, исправьте очистку.
- Найдите в коде проверки `typeof window` и флаги монтирования — кандидаты на замену `browser()`.
- Если анимации переходов сделаны сторонней библиотекой, оцените переход на ViewTransition: меньше зависимостей, меньше JavaScript.
- Если на сайте есть CSP, проверьте, можно ли теперь включить Trusted Types.
Наше мнение
Мы считаем 19.3 полезным релизом без драмы: он закрывает частые обходные решения, которые годами жили в проектах. Больше всего выиграют интерфейсы с навигацией — каталоги, личные кабинеты, CRM. Плавный переход между списком и карточкой теперь делается штатно, без тяжёлых библиотек анимации. Что мы советуем клиентам: обновляться вместе с Next.js 16.4.1 и не переписывать работающие анимации без необходимости — новые возможности использовать в новых экранах.
Материалы для проверки
Если нужна реализация
Состав работ зависит от текущего проекта и подтверждённой причины. Можно обсудить диагностику или разработку подходящего решения.
Вопросы и ответы
Когда вышел React 19.3?
9 сентября 2026 года. 6 октября он вошёл в состав Next.js 16.4.
Есть ли в React 19.3 ломающие изменения?
В анонсе их нет. Но изменилось поведение: в Strict Mode при гидрации эффекты вызываются дважды, переходы рендерятся независимо, обновления от resize группируются.
Что делает API browser()?
Компонент с use(browser()) не рендерится на сервере: в HTML попадает fallback из Suspense, а в браузере компонент работает обычно. Это замена проверкам typeof window.
Нужна ли библиотека анимаций для переходов?
Для многих сценариев — нет: стабильный ViewTransition использует браузерный View Transition API. Сложные анимации всё ещё удобнее делать специализированными библиотеками.
Работает ли ViewTransition в React Native?
Пока нет. По данным команды React, компонент работает только в DOM, поддержка других платформ в разработке.
Как React 19.3 влияет на SEO?
Напрямую не влияет. Но browser() позволяет аккуратно убрать из серверного HTML только браузерные части, не ломая гидрацию, — важный контент страницы при этом остаётся в HTML.