React постепенно развивает историю с переходами интерфейса, и один из свежих шагов в этом направлении — API addTransitionType. Он позволяет явно пометить, почему именно произошёл transition, чтобы дальше использовать эту причину для разных анимаций и сценариев отображения.
Отдельно интересно то, что эту возможность уже начинает подхватывать и экосистема. В обсуждении интеграции в Next.js описан проп transitionTypes для <Link>, который позволяет передать массив строк с типами перехода. Во время навигации Next.js вызывает React.addTransitionType для каждого указанного типа. Иными словами, теперь можно не просто сделать transition, а ещё и сказать React и браузеру: это переход вперёд, это свайп, это возврат назад или любой другой смысловой тип.
Важно, что такая механика работает только в App Router, потому что именно он опирается на Transitions при навигации. В Pages Router этот API фактически игнорируется: ссылки не ломаются, но transitionTypes там не дают эффекта. Это сделано затем, чтобы можно было создавать общие link-компоненты без лишних развилок в коде.
С точки зрения архитектуры у такого решения есть важный плюс. Обсуждался и другой вариант — передавать в <Link> что-то вроде navigateAction, внутри которого уже вызывался бы addTransitionType. Но это потребовало бы лишней границы между сервером и клиентом: функции нельзя свободно передавать из Server Components в Client Components. Поэтому вариант с массивом строк оказался практичнее.
Что такое addTransitionType
addTransitionType — это новый API React, доступный пока только в Canary и Experimental-каналах. Он позволяет указать причину transition внутри startTransition.
startTransition(() => {
addTransitionType('my-transition-type');
setState(newState);
});Сам по себе вызов ничего не возвращает. Его задача — пометить текущий transition одним или несколькими типами, чтобы затем на эту информацию можно было опереться при анимации интерфейса.
Базовый пример
import { startTransition, addTransitionType } from 'react';
function Submit({ action }) {
function handleClick() {
startTransition(() => {
addTransitionType('submit-click');
action();
});
}
return <button onClick={handleClick}>Click me</button>;
}В этом примере React запоминает, что transition был вызван действием submit-click. Дальше этот контекст можно использовать для настройки поведения ViewTransition.
Как это связано с ViewTransition
Сегодня типы переходов особенно полезны вместе с ViewTransition. React может пробросить тип transition дальше, чтобы анимации зависели не только от факта обновления интерфейса, но и от его причины.
React описывает три основных способа использовать эти типы:
1. Через browser view transition types
Когда ViewTransition активируется из transition, React добавляет собранные transition-типы как browser view transition types. Это позволяет настраивать анимации через CSS-области видимости.
function Component() {
return (
<ViewTransition>
<div>Hello</div>
</ViewTransition>
);
}
startTransition(() => {
addTransitionType('my-transition-type');
setShow(true);
});:root:active-view-transition-type(my-transition-type) {
&::view-transition-...(...) {
...
}
}Так можно по-разному анимировать разные сценарии навигации — например, движение вперёд, назад или появление нового экрана.
2. Через объект классов у ViewTransition
Можно связать определённый transition type с конкретным CSS-классом:
function Component() {
return (
<ViewTransition enter={{
'my-transition-type': 'my-transition-class',
}}>
<div>Hello</div>
</ViewTransition>
);
}
// ...
startTransition(() => {
addTransitionType('my-transition-type');
setState(newState);
});Если совпало несколько типов, React объединит их. Если не совпал ни один — будет использован специальный ключ default. А если хотя бы один тип имеет значение none, то ViewTransition вообще отключится для этого случая.
Особенно интересен сценарий навигации в интерфейсах, где важно различать направление:
<ViewTransition
enter={{
'navigation-back': 'enter-right',
'navigation-forward': 'enter-left',
}}
exit={{
'navigation-back': 'exit-right',
'navigation-forward': 'exit-left',
}}
>То есть интерфейс может по-настоящему «понимать», в какую сторону движется пользователь, и анимироваться соответственно.
3. Через события ViewTransition
Есть и императивный путь — через события:
<ViewTransition onUpdate={(inst, types) => {
if (types.includes('navigation-back')) {
...
} else if (types.includes('navigation-forward')) {
...
} else {
...
}
}}>Это удобно, если для разных причин transition нужна не только разная CSS-анимация, но и разная логика поведения.
Важные ограничения
У addTransitionType есть несколько особенностей:
- если объединяются несколько transitions, их типы тоже собираются вместе;
- одному transition можно назначить сразу несколько типов;
- после каждого commit типы сбрасываются;
- если после
startTransitionпоказался fallback из<Suspense>, он будет связан с этими типами, а вот последующее раскрытие контента — уже нет.
Это важно учитывать, если вы строите сложные цепочки загрузки и анимации.
Что это даёт Next.js уже сейчас
С практической точки зрения самое интересное здесь — не сам API React, а то, что он начинает находить применение в реальном фреймворке.
В Next.js появляется возможность передавать transitionTypes в ссылки App Router. Это открывает путь к более осмысленным переходам между страницами: не просто «был переход», а «это был свайп», «возврат назад», «переход в карточку», «переход в следующий экран» и так далее.
Примерно так это выглядит концептуально:
<Link href="/profile" transitionTypes={['navigation-forward', 'slide']} />Во время навигации Next.js вызывает addTransitionType для каждого указанного типа, а дальше эти типы можно использовать в ViewTransition для настройки анимации.
Именно в этом и состоит главный смысл всей истории: React даёт язык для обозначения причины transition, а Next.js начинает применять этот язык к навигации между страницами.
Что пока не решено
При этом даже обсуждаемое решение не закрывает все сценарии. В частности, отдельно отмечалось, что ни navigateAction, ни transitionTypes сами по себе не решают задачу включения view transitions для MPA-навигаций. То есть это важный шаг вперёд, но не финальная точка развития API.
Итог
Получается довольно красивая связка. React вводит addTransitionType — механизм, который позволяет маркировать причину перехода. Next.js, в свою очередь, начинает использовать эту идею в навигации App Router через transitionTypes у <Link>. В результате разработчик получает более выразительный контроль над анимациями и может строить интерфейсы, где переходы ощущаются не как случайный визуальный эффект, а как часть навигационной логики.
Теги: react, nextjs, view-transitions