home

blog

back to blog
experimental view transition

experimental view transition

article

React ViewTransition Implementation

How ViewTransition Works Under the Hood

Under the hood, React applies view-transition-name to inline styles of the nearest DOM node nested inside the <ViewTransition> component. If there are multiple sibling DOM nodes like <ViewTransition><div /><div /></ViewTransition> 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.

Automatic Coordination

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 of trigger ViewTransitions in the past, we recommend that you migrate to the built-in way.

Batching and Queueing

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.

Lifecycle and Execution Order

The getSnapshotBeforeUpdate life-cycle 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 useInsertionEffects
  • 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.

Special Cases

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.