개요
<ViewTransition>
은 React의 실험적(Experimental) 컴포넌트로, Transition 내부에서 업데이트되는 요소에 애니메이션을 적용할 수 있게 해줍니다. 예를 들어, 요소가 추가/삭제/업데이트/공유될 때 부드러운 전환 효과를 줄 수 있습니다.
⚠️ 이 API는 실험적이며, 정식(stable) 릴리즈에는 포함되어 있지 않습니다. 프로덕션에서는 사용하지 마세요.
import { unstable_ViewTransition as ViewTransition } from 'react';
<ViewTransition>
<div>...</div>
</ViewTransition>
Reference
<ViewTransition>
Transition 내부에서 요소가 추가, 삭제, 업데이트, 공유될 때 애니메이션을 적용합니다. 기본적으로 브라우저의 cross-fade(크로스 페이드) 애니메이션이 적용되며, props로 커스텀 애니메이션을 지정할 수 있습니다.
Props
enter
(optional): enter 트리거 시 적용할 View Transition Class(문자열 또는 객체).exit
(optional): exit 트리거 시 적용할 View Transition Class(문자열 또는 객체).update
(optional): update 트리거 시 적용할 View Transition Class(문자열 또는 객체).share
(optional): 공유 요소 전환 시 적용할 View Transition Class(문자열 또는 객체).default
(optional): 기본 애니메이션 클래스(문자열 또는 객체).name
(optional): 공유 요소 전환 시 사용할 고유 이름.children
: 애니메이션을 적용할 실제 UI 요소.
동작 방식
- React는
<ViewTransition>
내부의 가장 가까운 DOM 노드에view-transition-name
스타일을 적용합니다. - 여러 형제 DOM 노드가 있을 경우, 각각 고유한 이름이 부여됩니다.
- React가 DOM 변경을 적용할 때 자동으로
startViewTransition
을 호출하므로, 직접 호출할 필요가 없습니다. - 여러 ViewTransition이 동시에 실행 중이면, 이전 애니메이션이 끝난 후 다음 애니메이션이 실행됩니다. 중간에 여러 업데이트가 발생하면 마지막 상태로 한 번만 애니메이션됩니다.
사용법
요소의 등장/퇴장 애니메이션
<ViewTransition enter="slide-in" exit="slide-out">
<Video />
</ViewTransition>
enter
,exit
prop에 원하는 애니메이션 클래스를 지정할 수 있습니다.
공유 요소(Shared Element) 애니메이션
<ViewTransition name="profile-avatar">
<Avatar />
</ViewTransition>
- 같은 이름의 ViewTransition이 삭제되는 트리와 추가되는 트리에 동시에 존재하면, 두 요소 사이에 공유 요소 전환 애니메이션이 적용됩니다.
리스트 아이템 재정렬 애니메이션
{items.map(item => (
<ViewTransition key={item.id} name={`item-${item.id}`}>
<Item {...item} />
</ViewTransition>
))}
- 리스트의 순서가 바뀔 때 각 아이템에 애니메이션을 적용할 수 있습니다.
Suspense와 함께 사용하기
- Suspense로 감싼 콘텐츠가 준비되면, ViewTransition을 통해 부드럽게 나타나게 할 수 있습니다.
애니메이션 커스터마이즈
<ViewTransition default="slow-fade">
<Video />
</ViewTransition>
- CSS에서 view transition 클래스를 정의해 애니메이션 속도, 효과 등을 조절할 수 있습니다.
::view-transition-old(.slow-fade) {
animation-duration: 500ms;
}
::view-transition-new(.slow-fade) {
animation-duration: 500ms;
}
타입별 커스텀 애니메이션
<ViewTransition default={{
'navigation-back': 'slide-right',
'navigation-forward': 'slide-left',
}}>
<div>...</div>
</ViewTransition>
- addTransitionType API와 함께 사용하면, 네비게이션 방향 등 특정 상황에 따라 다른 애니메이션을 적용할 수 있습니다.
트러블슈팅
ViewTransition이 활성화되지 않는 경우
<ViewTransition>
은 반드시 DOM 노드보다 먼저 위치해야 합니다.
// 잘못된 예시
<div>
<ViewTransition>Hi</ViewTransition>
</div>
// 올바른 예시
<ViewTransition>
<div>Hi</div>
</ViewTransition>
동일한 name의 ViewTransition이 동시에 마운트될 때 오류
- 같은 name을 가진
<ViewTransition>
이 동시에 여러 개 마운트되면 오류가 발생합니다. 반드시 고유한 name을 부여하세요.
// 잘못된 예시
<ViewTransition name="item">...</ViewTransition>
<ViewTransition name="item">...</ViewTransition>
// 올바른 예시
<ViewTransition name={`item-${id}`}>...</ViewTransition>
참고 및 주의사항
- React가 자동으로 startViewTransition을 관리하므로, 직접 호출하지 않아야 합니다.
- flushSync가 중간에 실행되면 애니메이션이 건너뛰어질 수 있습니다.
- popstate(뒤로가기 등) 이벤트에서 startTransition이 동기적으로 끝나야 하므로, 이 경우 애니메이션이 실행되지 않을 수 있습니다. Navigation API를 사용하는 라우터를 권장합니다.
반응형