0

So I'm trying to create a simple page transition between pages in next.js using react-spring, however I can't get the unmounting component to fade out. Instead it just snaps out of the screen, while the new one fades in:

enter image description here

The screen then loads itself underneath, I'm really struggling to work out what's going on?

I've tried adding absolute positions to the from and/or the leave keys, but to no avail

//_app.js

import "../styles/globals.css";
import { useTransition, animated } from "react-spring";
import { useRouter } from "next/router";

function MyApp({ Component, pageProps }) {
  const router = useRouter();
  const transition = useTransition(router, {
    key: router.pathname,
    from: { opacity: 0},
    enter: { opacity: 1 },
    leave: { opacity: 0},
    config: { duration: 1000 },
    // reset:true,
  });

  return transition((style, item) => {
    return (
      <animated.div style={style}>
        <Component {...pageProps} />
     </animated.div>
    );
  });

}

export default MyApp;

Any help would be great! Thank you

WillMaddicott
  • 512
  • 6
  • 20

1 Answers1

0

I think the reason this is going wrong for you is that you're using the Component from my app to render, but passing in the useRouter state to the useTransition hook, resulting in them being disconnected.

I got it to work using an additional array:

function MyApp({ Component, pageProps }) {
  const router = useRouter();

  // initial state
  const [compoentArray, setComponentArray] = useState([
    <Component key={router.pathname} {...pageProps} />,
  ]);

  const transitions = useTransition(compoentArray, {
    from: { opacity: 0 },
    enter: [{ opacity: 1 }],
    leave: {
      position: "absolute",
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      opacity: 0,
    },
    delay: 200,
  });

  // Updates the array when needed. Avoids rerenders
  useEffect(() => {
    if (compoentArray[0].key === router.pathname) {
      return;
    }
    setComponentArray([<Component key={router.pathname} {...pageProps} />]);
  }, [Component, pageProps, router, compoentArray]);


  return (
      <div>
        {transitions((style, item) => {
          // Render items managed by react-spring
          return <animated.div style={style}>{item}</animated.div>;
        })}
      </div>
  );
}