DEV Community

Cover image for View Transition Animation in React.js App
Techie
Techie

Posted on • Edited on

1

View Transition Animation in React.js App

Other day me want create quick remove items from list animation for site. This time skip React Transition Group, try new View Transition, save time.

Why write lot code when few code do trick.

View Transition API Chrome only, but me no care.

Crux is document.startViewTransition.

But need establish DOM before state, after state, but React.js don’t allow.

React.js reactive. Not synchronous. document.startViewTransition need synchronous.

Ask Google learn:

import { flushSync } from "react-dom";

flushSync(() => setState(...));
Enter fullscreen mode Exit fullscreen mode

Me write hook:

import { useEffect, useState } from "react";
import { flushSync } from "react-dom";

export const useViewTransition =
  typeof document !== "undefined" && "startViewTransition" in document
    ? <T>(newValue: T) => {
        const [value, setValue] = useState(newValue);
        useEffect(() => {
          if (value !== newValue)
            document.startViewTransition(() => {
              flushSync(() => {
                setValue(newValue);
              });
            });
        }, [newValue]);
        return value;
      }
    : <T>(value: T) => value;
Enter fullscreen mode Exit fullscreen mode

If use useQuery

const { data: newMsgs } = useQuery({
  queryKey: ["msgs"],
  queryFn: msgs.all(25)
});

const msgs = useViewTransition(newMsgs);

return (
  <ol>
    {msgs?.map(item => (
      <li 
        key={item.id} 
        style={{
          viewTransitionName: "msg-" + item.id,
          viewTransitionClass: "mymsg",
        }}
      >
        {item.title}
      </li>
    ))}
  </ol>
);
Enter fullscreen mode Exit fullscreen mode

Now when useQuery update, hook call document.startViewTransition then setState.

Need global CSS

Me add global.css:

@supports (view-transition-name: none) {
  ::view-transition-group(root) {
    animation-duration: 0s;
  }
  ::view-transition-group(.mymsg) {
    animation-duration: 0.4s;
  }
}
Enter fullscreen mode Exit fullscreen mode

This tell Chrome: don’t transition whole page, only transition list items.

Now message list animation work. Very nice.

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay