--- title: version: canary --- **The `` API is currently only available in React’s Canary and Experimental channels.** [Learn more about React’s release channels here.](/community/versioning-policy#all-release-channels) `` lets you animate a component tree with Transitions and Suspense. ```js import {ViewTransition} from 'react';
...
```
--- ## Reference {/*reference*/} ### `` {/*viewtransition*/} Wrap a component tree in `` to animate it: ```js ``` [See more examples below.](#usage) #### How does `` work? {/*how-does-viewtransition-work*/} Under the hood, React applies `view-transition-name` to inline styles of the nearest DOM node nested inside the `` component. If there are multiple sibling DOM nodes like `
` then React adds a suffix to the name to make each unique but conceptually they're part of the same one. React doesn't apply these eagerly but only at the time that boundary should participate in an animation. React automatically calls `startViewTransition` itself behind the scenes so you should never do that yourself. In fact, if you have something else on the page running a ViewTransition React will interrupt it. So it's recommended that you use React itself to coordinate these. If you had other ways to trigger ViewTransitions in the past, we recommend that you migrate to the built-in way. If there are other React ViewTransitions already running then React will wait for them to finish before starting the next one. However, importantly if there are multiple updates happening while the first one is running, those will all be batched into one. If you start A->B. Then in the meantime you get an update to go to C and then D. When the first A->B animation finishes the next one will animate from B->D. The `getSnapshotBeforeUpdate` lifecycle will be called before `startViewTransition` and some `view-transition-name` will update at the same time. Then React calls `startViewTransition`. Inside the `updateCallback`, React will: - Apply its mutations to the DOM and invoke `useInsertionEffect`. - Wait for fonts to load. - Call `componentDidMount`, `componentDidUpdate`, `useLayoutEffect` and refs. - Wait for any pending Navigation to finish. - Then React will measure any changes to the layout to see which boundaries will need to animate. After the ready Promise of the `startViewTransition` is resolved, React will then revert the `view-transition-name`. Then React will invoke the `onEnter`, `onExit`, `onUpdate` and `onShare` callbacks to allow for manual programmatic control over the animations. This will be after the built-in default ones have already been computed. If a `flushSync` happens to get in the middle of this sequence, then React will skip the Transition since it relies on being able to complete synchronously. After the finished Promise of the `startViewTransition` is resolved, React will then invoke `useEffect`. This prevents those from interfering with the performance of the animation. However, this is not a guarantee because if another `setState` happens while the animation is running it'll still have to invoke the `useEffect` earlier to preserve the sequential guarantees. #### Props {/*props*/} - **optional** `name`: A string or object. The name of the View Transition used for shared element transitions. If not provided, React will use a unique name for each View Transition to prevent unexpected animations. - [View Transition Class](#view-transition-class) props. - [View Transition Event](#view-transition-event) props. #### Caveats {/*caveats*/} - Only use `name` for [shared element transitions](#animating-a-shared-element). For all other animations, React automatically generates a unique name to prevent unexpected animations. - By default, `setState` updates immediately and does not activate ``, only updates wrapped in a [Transition](/reference/react/useTransition), [``](/reference/react/Suspense), or `useDeferredValue` activate ViewTransition. - `` creates an image that can be moved around, scaled and cross-faded. Unlike Layout Animations you may have seen in React Native or Motion, this means that not every individual Element inside of it animates its position. This can lead to better performance and a more continuous feeling, smooth animation compared to animating every individual piece. However, it can also lose continuity in things that should be moving by themselves. So you might have to add more `` boundaries manually as a result. - Currently, `` only works in the DOM. We're working on adding support for React Native and other platforms. #### Animation triggers {/*animation-triggers*/} React automatically decides the type of View Transition animation to trigger: - `enter`: If a `ViewTransition` is the first component inserted in this Transition, then this will activate. - `exit`: If a `ViewTransition` is the first component deleted in this Transition, then this will activate. - `update`: If a `ViewTransition` has any DOM mutations inside it that React is doing (such as a prop changing) or if the `ViewTransition` boundary itself changes size or position due to an immediate sibling. If there are nested `ViewTransition` then the mutation applies to them and not the parent. - `share`: If a named `ViewTransition` is inside a deleted subtree and another named `ViewTransition` with the same name is part of an inserted subtree in the same Transition, they form a Shared Element Transition, and it animates from the deleted one to the inserted one. By default, `` animates with a smooth cross-fade (the browser default view transition). You can customize the animation by providing a [View Transition Class](#view-transition-class) to the `` component for each kind of trigger (see [Styling View Transitions](#styling-view-transitions)), or by using [ViewTransition Events](#view-transition-events) to control the animation with JavaScript using the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API). #### Always check `prefers-reduced-motion` {/*always-check-prefers-reduced-motion*/} Many users may prefer not having animations on the page. React doesn't automatically disable animations for this case. We recommend always using the `@media (prefers-reduced-motion)` media query to disable animations or tone them down based on user preference. In the future, CSS libraries may have this built-in to their presets. ### View Transition Class {/*view-transition-class*/} `` provides props to define what animations trigger: ```js ``` #### Props {/*view-transition-class-props*/} - **optional** `enter`: `"auto"`, `"none"`, a string, or an object. - **optional** `exit`: `"auto"`, `"none"`, a string, or an object. - **optional** `update`: `"auto"`, `"none"`, a string, or an object. - **optional** `share`: `"auto"`, `"none"`, a string, or an object. - **optional** `default`: `"auto"`, `"none"`, a string, or an object. #### Caveats {/*view-transition-class-caveats*/} - If `default` is `"none"` then all other triggers are turned off unless explicitly listed. #### Values {/*view-transition-values*/} View Transition class values can be: - `auto`: the default. Uses the browser default animation. - `none`: disable animations for this type. - ``: a custom CSS class name to use for [customizing View Transitions](#styling-view-transitions). Object values can be an object with string keys and a value of `auto`, `none` or a custom className: - `{[type]: value}`: applies `value` if the animation matches the [Transition Type](/reference/react/addTransitionType). - `{default: value}`: the default value to apply if no [Transition Type](/reference/react/addTransitionType) is matched. For example, you can define a ViewTransition as: ```js ``` See [Styling View Transitions](#styling-view-transitions) for how to define CSS classes for custom animations. --- ### View Transition Event {/*view-transition-event*/} View Transition Events allow you to control the animation with JavaScript using the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API): ```js {/* ... */}} onExit={instance => {/* ... */}} /> ``` #### Props {/*view-transition-event-props*/} - **optional** `onEnter`: Called when an "enter" animation is triggered. - **optional** `onExit`: Called when an "exit" animation is triggered. - **optional** `onShare`: Called when a "share" animation is triggered. - **optional** `onUpdate`: Called when an "update" animation is triggered. #### Caveats {/*view-transition-event-caveats*/} - Only one event fires per `` per Transition. `onShare` takes precedence over `onEnter` and `onExit`. - Each event should return a **cleanup function**. The cleanup function is called when the View Transition finishes, allowing you to cancel or cleanup any animations. #### Arguments {/*view-transition-event-arguments*/} Each event receives two arguments: - `instance`: A View Transition instance that provides access to the view transition [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API/Using#the_view_transition_process) - `old`: The `::view-transition-old` pseudo-element. - `new`: The `::view-transition-new` pseudo-element. - `name`: The `view-transition-name` string for this boundary. - `group`: The `::view-transition-group` pseudo-element. - `imagePair`: The `::view-transition-image-pair` pseudo-element. - `types`: An `Array` of [Transition Types](/reference/react/addTransitionType) included in the animation. Empty array if no types were specified. For example, you can define a `onEnter` event that drives the animation using JavaScript: ```js { const anim = instance.new.animate([{opacity: 0}, {opacity: 1}], { duration: 500, }); return () => anim.cancel(); }}>
...
``` See [Animating with JavaScript](#animating-with-javascript) for more examples. --- ## Styling View Transitions {/*styling-view-transitions*/} In many early examples of View Transitions around the web, you'll have seen using a [`view-transition-name`](https://developer.mozilla.org/en-US/docs/Web/CSS/view-transition-name) and then style it using `::view-transition-...(my-name)` selectors. We don't recommend that for styling. Instead, we normally recommend using a View Transition Class instead. To customize the animation for a `` you can provide a View Transition Class to one of the activation props. The View Transition Class is a CSS class name that React applies to the child elements when the ViewTransition activates. For example, to customize an "enter" animation, provide a class name to the `enter` prop: ```js ``` When the `` activates an "enter" animation, React will add the class name `slide-in`. Then you can refer to this class using [view transition pseudo selectors](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API#pseudo-elements) to build reusable animations: ```css ::view-transition-group(.slide-in) { } ::view-transition-old(.slide-in) { } ::view-transition-new(.slide-in) { } ``` In the future, CSS libraries may add built-in animations using View Transition Classes to make this easier to use. --- ## Usage {/*usage*/} ### Animating an element on enter/exit {/*animating-an-element-on-enter*/} Enter/Exit Transitions trigger when a `` is added or removed by a component in a transition: ```js {3} function Child() { return (
Hi
); } function Parent() { const [show, setShow] = useState(); if (show) { return ; } return null; } ``` When `setShow` is called, `show` switches to `true` and the `Child` component is rendered. When `setShow` is called inside `startTransition`, and `Child` renders a `ViewTransition` before any other DOM nodes, an `enter` animation is triggered. When `show` switches back to `false`, an `exit` animation is triggered. ```js src/Video.js hidden function Thumbnail({video, children}) { return (