addTransitionType

2026. 9. 15. 01:59·리액트/레퍼런스 (react 19ver)

좋습니다. addTransitionType은 바로 직전에 배운 <ViewTransition>을 한 단계 더 세밀하게 제어하는 API입니다.

한 문장으로 먼저 잡으면:

addTransitionType은 “이번 Transition이 왜 발생했는지”에 이름표를 붙이는 API입니다.

예를 들어 둘 다 페이지 전환이지만:

뒤로 가기
앞으로 가기
검색 결과 갱신
폼 제출

은 시각적으로 다르게 처리하고 싶을 수 있습니다. 이때 Transition에 "navigation-back", "navigation-forward" 같은 원인(type)을 붙이고, <ViewTransition>이 그 type을 보고 다른 애니메이션을 선택하게 만들 수 있습니다. (React)

1. 가장 기본적인 사용법

공식 문서의 기본 패턴은 다음입니다.

import {
  startTransition,
  addTransitionType
} from 'react';

startTransition(() => {
  addTransitionType('my-transition-type');
  setState(newState);
});

중요한 구조는:

startTransition
└─ addTransitionType(...)
└─ state update

입니다.

addTransitionType을 호출하면 React는 현재 Transition에 해당 문자열을 하나의 cause, 즉 발생 원인으로 연결합니다. type에는 아무 문자열이나 사용할 수 있고, 반환값은 없습니다. (React)


2. 왜 이게 필요한가?

이전 <ViewTransition> 페이지에서 이런 코드를 봤습니다.

<ViewTransition
  enter="slide-in"
  exit="slide-out"
>
  <Page />
</ViewTransition>

이것만으로는:

Page가 enter하면 항상 slide-in
Page가 exit하면 항상 slide-out

입니다.

그런데 navigation 방향에 따라 다르게 하고 싶다면 어떨까요?

Home → Product
= 앞으로 이동

Product → Home
= 뒤로 이동

UX를 이렇게 만들고 싶을 수 있습니다.

앞으로 이동
→ 새 화면이 오른쪽에서 왼쪽으로

뒤로 이동
→ 새 화면이 왼쪽에서 오른쪽으로

하지만 <ViewTransition> 입장에서는 둘 다 단순히:

enter
exit

일 뿐입니다.

그래서 추가 정보가 필요합니다.

이 Transition이 "forward" 때문에 일어난 건지
"back" 때문에 일어난 건지

그 정보를 붙이는 API가:

addTransitionType(...)

입니다.


3. Transition Type은 animation 종류가 아니다

이 부분을 정확히 구분해야 합니다.

addTransitionType('navigation-forward');

라고 한다고 React가 자동으로:

앞으로 슬라이드해라

라고 해석하는 게 아닙니다.

"navigation-forward"는 그냥 의미를 가진 문자열 라벨입니다.

React는:

이번 Transition의 type:
["navigation-forward"]

라고 기억합니다.

그 후 우리가 <ViewTransition>이나 CSS에서:

navigation-forward면 어떤 animation을 쓸지

정합니다.

즉:

Transition Type
= 원인/의도 정보

Animation Class
= 실제 시각 효과

입니다.


4. 실제 navigation 예제

예를 들어 간단한 router가 있다고 해봅시다.

function navigateForward(url) {
  startTransition(() => {
    addTransitionType('navigation-forward');
    setUrl(url);
  });
}

function navigateBack(url) {
  startTransition(() => {
    addTransitionType('navigation-back');
    setUrl(url);
  });
}

그러면 React 입장에서:

setUrl('/products')

라는 동일한 종류의 state update라도:

navigation-forward

인지:

navigation-back

인지 구분할 수 있습니다.

이제 <ViewTransition>이 그 차이를 활용할 수 있습니다.


5. 첫 번째 활용법: <ViewTransition> class를 type에 따라 고르기

공식 문서에서 가장 이해하기 쉬운 활용법입니다.

<ViewTransition
  enter={{
    'navigation-back': 'enter-right',
    'navigation-forward': 'enter-left',
  }}
  exit={{
    'navigation-back': 'exit-right',
    'navigation-forward': 'exit-left',
  }}
>
  <Page />
</ViewTransition>

이제:

startTransition(() => {
  addTransitionType('navigation-forward');
  setPage(nextPage);
});

가 발생하면:

enter → enter-left
exit  → exit-left

를 선택할 수 있고,

startTransition(() => {
  addTransitionType('navigation-back');
  setPage(previousPage);
});

이면:

enter → enter-right
exit  → exit-right

가 됩니다. (React)

이 패턴이 addTransitionType의 핵심 사용 사례라고 보면 됩니다.


6. <ViewTransition>의 trigger 종류와 type은 서로 다른 축이다

직전 페이지에서 배운 것을 기억해봅시다.

ViewTransition에는:

enter
exit
update
share
layout

같은 변화 종류가 있습니다.

그리고 지금 배우는:

navigation-forward
navigation-back
submit-click

같은 것은 Transition Type입니다.

즉 두 개는 다른 질문에 답합니다.

enter / exit / update
→ UI에 "무슨 변화"가 일어났는가?

navigation-forward / back
→ "왜" 그 변화가 일어났는가?

그래서 조합할 수 있습니다.

<ViewTransition
  enter={{
    'navigation-forward': 'enter-from-right',
    'navigation-back': 'enter-from-left',
  }}
  exit={{
    'navigation-forward': 'exit-to-left',
    'navigation-back': 'exit-to-right',
  }}
>

이걸 표로 보면:

변화 종류 Transition Type animation
enter navigation-forward enter-from-right
exit navigation-forward exit-to-left
enter navigation-back enter-from-left
exit navigation-back exit-to-right

입니다.


7. 하나의 Transition에 type을 여러 개 붙일 수도 있다

공식 문서의 중요한 caveat입니다.

startTransition(() => {
  addTransitionType('navigation-forward');
  addTransitionType('mobile');
  setPage(nextPage);
});

처럼 하나의 Transition에 여러 type을 추가할 수 있습니다. (React)

개념적으로:

Transition Types

[
  "navigation-forward",
  "mobile"
]

이 됩니다.

따라서 type을 하나의 enum처럼만 생각할 필요는 없습니다.

현재 Transition에 적용되는 여러 의미적 태그

에 가깝습니다.


8. 여러 Transition이 합쳐지면 type도 합쳐진다

React는 여러 Transition을 하나로 처리할 수 있습니다.

공식 문서는 이 경우 모든 Transition Type을 수집한다고 설명합니다. (React)

예를 들어 개념적으로:

Transition A
→ "navigation"

Transition B
→ "refresh"

가 같은 작업에 합쳐지면:

["navigation", "refresh"]

처럼 둘 다 존재할 수 있습니다.

그래서 ViewTransition API에서도 type을 단일 문자열이 아니라 여러 개가 존재할 수 있는 것으로 설계합니다.


9. 여러 type이 <ViewTransition>에 동시에 match되면?

예를 들어:

<ViewTransition
  enter={{
    navigation: 'slide',
    urgent: 'fast',
  }}
>

이고 현재 Transition에:

["navigation", "urgent"]

가 모두 붙어 있다고 합시다.

공식 문서에 따르면 여러 type이 match되면 class 이름들이 합쳐집니다. (React)

즉 개념적으로:

"slide fast"

처럼 둘 다 적용됩니다.

이 때문에 type을 조합 가능한 의미 단위로 설계할 수도 있습니다.


10. 아무 type도 match하지 않는다면 default

다음처럼 작성할 수도 있습니다.

<ViewTransition
  enter={{
    'navigation-forward': 'enter-left',
    'navigation-back': 'enter-right',
    default: 'fade-in',
  }}
>

현재 Transition type이:

"search-update"

인데 별도 entry가 없다면:

default → fade-in

이 사용됩니다. (React)

따라서:

특정 Transition만 특별 처리
나머지는 기본 animation

이라는 설계가 가능합니다.


11. "none"은 특별하다

예를 들어:

<ViewTransition
  update={{
    'background-update': 'none',
    default: 'cross-fade',
  }}
>

현재 Transition에:

background-update

가 포함되어 있으면 ViewTransition animation을 끌 수 있습니다.

공식 문서에서는 여러 matching type 중 하나라도 값이 "none"이면 "none"이 우선하며, 그 ViewTransition 자체가 비활성화된다고 설명합니다. (React)

즉:

type A → slide
type B → none

둘 다 현재 Transition에 존재

결과 → none

입니다.

이건 특정 종류의 업데이트에서는 애니메이션을 명시적으로 금지하고 싶을 때 유용합니다.


12. 두 번째 활용법: 브라우저 View Transition Type과 연결

조금 더 저수준 사용법입니다.

React에서:

startTransition(() => {
  addTransitionType('navigation-forward');
  setPage(nextPage);
});

하고 해당 Transition으로 <ViewTransition>이 활성화되면 React가 이 type을 브라우저 View Transition Type에도 연결합니다. (React)

그러면 CSS에서:

:root:active-view-transition-type(navigation-forward) {
  /* 이 Transition일 때만 적용 */
}

처럼 선택할 수 있습니다.

즉 React의 의미적 정보:

navigation-forward

를 CSS 쪽에서도 알 수 있습니다.


13. 왜 ViewTransition class 방식과 browser type 방식 둘 다 있을까?

두 방식의 레벨이 다릅니다.

React <ViewTransition> class 방식

<ViewTransition
  enter={{
    'navigation-forward': 'enter-left'
  }}
>

특정 React ViewTransition boundary가:

enter일 때
+
navigation-forward일 때

어떤 class를 받을지 결정합니다.

Browser View Transition Type 방식

:root:active-view-transition-type(navigation-forward) {
  ...
}

현재 전체 browser View Transition 자체의 type을 기준으로 CSS를 적용합니다.

즉:

React component 단위 제어
vs
전체 browser transition 상태 단위 제어

라는 차이가 있습니다.

일반적인 React 코드에서는 <ViewTransition> class 방식이 이해하기 더 쉽습니다.


14. 세 번째 활용법: onEnter, onUpdate 같은 이벤트

직전 페이지에서:

<ViewTransition
  onUpdate={(instance) => {
    ...
  }}
>

를 봤습니다.

addTransitionType을 사용하면 callback의 두 번째 인자로 type 목록도 받을 수 있습니다.

공식 문서 예시는:

<ViewTransition
  onUpdate={(inst, types) => {
    if (types.includes('navigation-back')) {
      // back animation
    } else if (types.includes('navigation-forward')) {
      // forward animation
    } else {
      // default
    }
  }}
>

형태입니다. (React)

즉 imperative animation을 쓸 때도:

왜 이 Transition이 발생했는가?

를 확인할 수 있습니다.


15. CSS보다 JS animation이 필요한 경우

예를 들어:

<ViewTransition
  onEnter={(instance, types) => {
    if (types.includes('navigation-forward')) {
      const animation = instance.new.animate(
        [
          { transform: 'translateX(100%)' },
          { transform: 'translateX(0)' },
        ],
        { duration: 300 }
      );

      return () => animation.cancel();
    }
  }}
>

같이 만들 수 있습니다.

여기서:

types
= Transition의 원인

instance
= View Transition snapshot 조작 대상

이라고 보면 됩니다.

따라서 addTransitionType 자체가 animation을 실행하는 게 아니라 animation 선택에 필요한 context를 전달하는 역할입니다.


16. addTransitionType은 어디서 호출해야 하나?

공식 문서의 기본 사용법은:

startTransition(() => {
  addTransitionType('submit-click');
  action();
});

입니다. (React)

즉 핵심은:

Transition scope 안에서 호출해야 한다.

입니다.

이런 구조로 기억하세요.

function handleForward() {
  startTransition(() => {
    addTransitionType('navigation-forward');
    navigate('/next');
  });
}

Transition의 원인을 붙이는 API이므로 Transition과 별개로 임의의 render에서 호출하는 식으로 사용하지 않습니다.


17. startTransition과 역할을 구분하자

이 둘은 자주 같이 보이기 때문에 헷갈릴 수 있습니다.

startTransition(() => {
  addTransitionType('navigation-forward');
  setPage(nextPage);
});

여기서:

startTransition

이 state update는 Transition이다.

라는 스케줄링 의미를 제공합니다.

addTransitionType

그리고 이 Transition의 원인은 navigation-forward다.

라는 의미적 metadata를 제공합니다.

즉:

startTransition
= 업데이트의 처리 방식

addTransitionType
= 업데이트의 원인 라벨

입니다.


18. addTransitionType과 <ViewTransition>도 역할이 다르다

마찬가지입니다.

addTransitionType
→ "왜" 변화했는지 표시

<ViewTransition>
→ "어디를 어떻게 animate할지" 정의

따라서 보통 흐름은:

사용자 행동
   ↓
startTransition
   ↓
addTransitionType("navigation-forward")
   ↓
state 변경
   ↓
React 렌더링
   ↓
<ViewTransition> 변화 감지
   ↓
현재 type 확인
   ↓
적절한 animation 선택

입니다.


19. 중요한 caveat: type은 commit마다 reset된다

이 페이지에서 가장 놓치기 쉬운 내용입니다.

공식 문서는:

Transition Types는 각 commit 이후 reset된다.

고 설명합니다. (React)

이게 무슨 뜻인지 Suspense로 보겠습니다.

startTransition(() => {
  addTransitionType('navigation-forward');
  setPage(<SlowPage />);
});

SlowPage가 suspend한다고 해봅시다.

첫 번째 commit:

기존 UI
→ Suspense fallback

이 commit은 startTransition과 직접 연결되어 있기 때문에:

navigation-forward

type이 있습니다.

하지만 나중에 데이터가 준비돼서:

fallback
→ 실제 SlowPage

로 reveal되는 건 별도의 commit입니다.

이때는 이전 type이 자동으로 이어지지 않습니다. (React)


20. Suspense와 연결해서 정확히 이해해보자

흐름을 보면:

startTransition
addTransitionType("navigation-forward")
setPage()
        │
        ▼
SlowPage suspend
        │
        ▼
Commit #1
fallback 표시
type = navigation-forward ✅

        ...데이터 기다림...

Commit #2
실제 콘텐츠 reveal
type = 없음 ❌

입니다.

즉 Transition Type은:

어떤 비동기 작업의 전체 수명 동안 유지되는 global context

가 아닙니다.

각 commit에서 적용되는 metadata입니다.

이건 꽤 중요한 차이입니다.


21. 왜 이렇게 설계됐을까?

보충 설명

addTransitionType은:

"이 Promise와 관련된 모든 향후 UI 업데이트는 forward다"

라는 의미가 아니라,

"현재 Transition으로 발생시키고 있는 이 UI 변경의 원인은 forward다"

에 가깝습니다.

Suspense reveal은 시간이 지난 뒤 다른 상황에서 별도의 React commit으로 일어날 수 있으므로 원래 type을 무조건 유지하면 오히려 잘못된 animation이 적용될 수 있습니다.

그래서 commit 단위로 reset되는 것으로 이해하면 자연스럽습니다.


22. 실제 router를 설계한다면

가장 대표적인 패턴을 만들어봅시다.

function Router() {
  const [page, setPage] = useState('/');

  function push(url) {
    startTransition(() => {
      addTransitionType('navigation-forward');
      setPage(url);
    });
  }

  function back(url) {
    startTransition(() => {
      addTransitionType('navigation-back');
      setPage(url);
    });
  }

  return (
    <ViewTransition
      enter={{
        'navigation-forward': 'page-enter-from-right',
        'navigation-back': 'page-enter-from-left',
      }}
      exit={{
        'navigation-forward': 'page-exit-to-left',
        'navigation-back': 'page-exit-to-right',
      }}
    >
      <Page route={page} />
    </ViewTransition>
  );
}

여기서 architecture를 보면:

Router
→ navigation 의미를 안다
→ addTransitionType 호출

ViewTransition
→ 시각적 표현을 안다
→ type별 animation 선택

으로 역할이 깔끔하게 나뉩니다.


23. 이 분리가 좋은 이유

Router 같은 로직에서는:

addTransitionType('navigation-forward');

만 알려줍니다.

Router가:

300ms
translateX(100%)
ease-out

같은 시각 정보를 알 필요가 없습니다.

반대로 <ViewTransition>에서는:

navigation-forward
→ slide-left

만 결정합니다.

즉:

도메인/행동 의미
navigation-forward

       ↓

시각적 표현
slide-left

을 분리할 수 있습니다.

이게 addTransitionType의 좋은 설계 포인트입니다.


24. 폼 제출에도 사용할 수 있다

공식 문서도:

addTransitionType('submit-click');

예제를 사용합니다. (React)

예를 들어:

function handleSubmit() {
  startTransition(() => {
    addTransitionType('form-submit');
    submitAction();
  });
}

그리고:

<ViewTransition
  update={{
    'form-submit': 'submit-transition',
    default: 'regular-update',
  }}
>
  <FormResult />
</ViewTransition>

처럼 할 수 있습니다.

따라서 Transition Type은 navigation 전용이 아닙니다.

navigation-forward
navigation-back
form-submit
filter-change
search
sort-change

처럼 앱의 의미에 맞춰 자유롭게 만들 수 있습니다.


25. 이름은 구현이 아니라 “원인” 중심이 좋다

보충 설명

이 API의 이름 자체가:

specify the cause of a transition

입니다.

따라서 이런 이름:

addTransitionType('slide-left');

보다는:

addTransitionType('navigation-forward');

가 더 좋은 모델인 경우가 많습니다.

왜냐하면:

navigation-forward

라는 의미는 유지하면서 디자인을 나중에:

slide-left
→ fade
→ zoom

로 자유롭게 바꿀 수 있기 때문입니다.

즉:

❌ animation 이름
addTransitionType("slide-left")

✅ 사용자 행동/원인
addTransitionType("navigation-forward")

처럼 separation of concerns를 가져갈 수 있습니다.


26. 여러 type을 조합한다면 역시 의미 중심으로

예를 들어:

startTransition(() => {
  addTransitionType('navigation-forward');
  addTransitionType('modal');
  setRoute(nextRoute);
});

처럼 만들 수 있습니다.

그러면 ViewTransition 쪽에서:

navigation-forward
→ 이동 방향 결정

modal
→ modal 특화 animation 추가

처럼 조합할 수 있습니다.

다만 type이 많아지면 interaction 설계가 복잡해지므로 “CSS class를 전달하는 우회 수단”처럼 남용하는 것은 피하는 편이 좋습니다.


27. addTransitionType은 현재 주로 ViewTransition용이다

공식 문서에서는 현재 Transition Type을 사용할 수 있는 주된 용도가 Transition의 원인에 따라 View Transition animation을 다르게 하는 것이라고 설명합니다.

그리고 향후 더 많은 사용처를 지원할 계획이라고 명시합니다. (React)

따라서 지금은 mental model을:

Transition에 metadata 추가
→ 현재 주요 소비자는 ViewTransition

이라고 잡으면 됩니다.


28. 지금까지의 API를 한꺼번에 연결

최근 배운 API를 한 흐름으로 보겠습니다.

사용자가 상품 목록에서 상품을 클릭합니다.

사용자 클릭
   ↓
startTransition(...)

React에게:

이건 non-urgent Transition이다

라고 알려줍니다.

그 안에서:

addTransitionType('navigation-forward');

를 호출합니다.

React에게:

이 Transition이 발생한 이유는
앞으로 navigation했기 때문이다

라고 알려줍니다.

state를 변경합니다.

setPage('product-detail');

새 화면 일부가 아직 준비 안 됐다면:

Suspense
→ loading/reveal 조율

합니다.

그리고 UI 변화가 <ViewTransition> 안에서 발생하면:

ViewTransition
→ enter / exit / update / share 확인
→ Transition Type 확인
→ 적절한 animation 선택

합니다.

전체 그림:

사용자 행동
   │
   ▼
startTransition
"이 update는 Transition"
   │
   ▼
addTransitionType
"원인은 navigation-forward"
   │
   ▼
setState
   │
   ▼
React render
   │
   ├── Suspense
   │     준비 상태 조율
   │
   ▼
commit
   │
   ▼
ViewTransition
   ├── 변화 종류: enter/exit/update/share
   └── 원인: navigation-forward
             │
             ▼
       animation 선택

이 흐름을 이해하면 addTransitionType은 어려운 API가 아닙니다.


핵심 정리

addTransitionType을 한 문장으로 설명하면:

현재 React Transition에 “왜 이 Transition이 발생했는지”를 나타내는 문자열 type을 추가하는 API입니다. (React)

기본 패턴은:

startTransition(() => {
  addTransitionType('navigation-forward');
  setState(newState);
});

입니다.

특히 다음을 기억하세요.

  1. type은 아무 문자열이나 사용할 수 있고 반환값은 없습니다.
  2. 하나의 Transition에 여러 type을 추가할 수 있습니다.
  3. 여러 Transition이 합쳐지면 그 type들도 함께 수집됩니다. (React)
  4. 현재 주요 용도는 <ViewTransition> animation을 Transition이 발생한 원인에 따라 다르게 선택하는 것입니다.
  5. <ViewTransition>의 enter/exit/update/share는 무슨 UI 변화가 일어났는지, Transition Type은 왜 그 변화가 일어났는지를 나타냅니다.
  6. type에 따른 View Transition Class, 브라우저 View Transition Type CSS, onEnter/onUpdate 등의 JS event 세 방식으로 활용할 수 있습니다. (React)
  7. Transition Type은 commit마다 reset됩니다. 따라서 Suspense fallback commit에는 type이 있을 수 있지만 나중의 content reveal commit까지 자동으로 유지되지는 않습니다. (React)

이해도 테스트

정답은 바로 알려주지 않겠습니다.

  1. 다음 코드에서 startTransition과 addTransitionType의 역할 차이를 각각 설명해보세요.
startTransition(() => {
  addTransitionType('navigation-forward');
  setPage(nextPage);
});
  1. <ViewTransition>의 enter와 "navigation-forward"라는 Transition Type은 어떤 점에서 서로 다른 정보를 나타낼까요?

  2. 다음처럼 한 Transition에 type을 두 개 추가하면 React는 어떻게 처리할까요?

startTransition(() => {
  addTransitionType('navigation-forward');
  addTransitionType('modal');
  setState(nextState);
});
  1. addTransitionType('slide-left')보다 addTransitionType('navigation-forward') 같은 이름이 일반적으로 더 좋은 이유는 무엇일까요?

  2. navigation-forward type이 붙은 Transition에서 Suspense fallback이 먼저 commit되고 실제 콘텐츠는 나중에 reveal된다면, 실제 콘텐츠가 reveal되는 commit에도 자동으로 navigation-forward가 남아 있을까요?

'리액트 > 레퍼런스 (react 19ver)' 카테고리의 다른 글

cacheSignal  (0) 2026.09.15
cache  (0) 2026.09.15
act  (0) 2026.09.15
<ViewTransition>  (0) 2026.09.15
<Activity>  (0) 2026.09.14
'리액트/레퍼런스 (react 19ver)' 카테고리의 다른 글
  • cacheSignal
  • cache
  • act
  • <ViewTransition>
배불뚱이
배불뚱이
  • 배불뚱이
    FE 개발자의 개발 기록
    배불뚱이
  • 전체
    오늘
    어제
    • 분류 전체보기 (24)
      • 리액트 (24)
        • 공식문서 강의 (19ver) (17)
        • 레퍼런스 (react 19ver) (7)
        • 레퍼런스 (react-dom 19ver) (0)
  • 공지사항

  • 인기 글

  • 태그

    Hook
    공식문서
    레퍼런스
    component
    react
  • hELLO· Designed By정상우.v4.10.6
배불뚱이
addTransitionType
상단으로

티스토리툴바