Page Transition Effect in NextJS

Before we start building any component for the transition, let’s briefly talk about how NextJS renders pages.

First, let’s take a look at _app.js:

export default function MyApp({ Component, pageProps }) {
return (
<Component {…pageProp…


This content originally appeared on DEV Community and was authored by AnxinYang

Before we start building any component for the transition, let's briefly talk about how NextJS renders pages.

First, let's take a look at _app.js:

export default function MyApp({ Component, pageProps }) {
  return (
      <Component {...pageProps} />
  );
}

The "_app.js" is the entry point for NextJS to start render page. When you navigation to a different page, the page component pass to MyApp as Component.

Therefore, in order to make a transition effect, we need to prevent

NextJS from rendering the new page before transition effect is done.

Now, let's create the layout component with some navigation links:


export default function TransitionLayout({ children }) {
  return (
    <div>
      <nav>
        <Link href="/">Home</Link>
        <Link href="/about">About</Link>
      </nav>
      <div>
        {children}
      </div>
    </div>
  );
}

And add to _app.js

function MyApp({ Component, pageProps }) {
  return (
    <TransitionLayout>
      <Component {...pageProps} />
    </TransitionLayout>
  );
}

Now, let's start working on the TransitionLayout

First, we need to prevent the rendering the new page

We can add a state to hold the current children, and only render the displayChildren.

We use children as the default value for displayChildren.


export default function TransitionLayout({ children }) {
  const [displayChildren, setDisplayChildren] = useState(children);
  return (
    <div>
      ...
      <div>
        {displayChildren}
      </div>
    </div>
  );
}

Now, if you click the link, the content of the page will not change.

Next, we add css and transition stage

.content {
  opacity: 0;
  background-color: cornflowerblue;
  transition: 1s;
}

.fadeIn {
  opacity: 1;
}

export default function TransitionLayout({ children }) {
  const [displayChildren, setDisplayChildren] = useState(children);
  const [transitionStage, setTransitionStage] = useState("fadeOut");
  ...
  return (
    <div>
      ...
      <div
        className={`${styles.content} ${styles[transitionStage]}`}
      >
        {displayChildren}
      </div>
    </div>
  );
}

Now, the component will by default at 'fadeOut' stage, and we want to let it enter the 'fadeIn' stage at first time render, so let's add:

  useEffect(() => {
    setTransitionStage("fadeIn");
  }, []);

Next, we want the component to enter 'fadeOut' when new children is received.

  useEffect(() => {
    if (children !== displayChildren) setTransitionStage("fadeOut");
  }, [children, setDisplayChildren, displayChildren]);

And, render new children when 'fadeOut'is done, then re-enter 'fadeIn' stage.

  ...
  return(
      ...
      <div
        onTransitionEnd={() => {
          if (transitionStage === "fadeOut") {
            console.log("fading out");
            setDisplayChildren(children);
            setTransitionStage("fadeIn");
          }
        }}
        className={`${styles.content} ${styles[transitionStage]}`}
      >
        {displayChildren}
      </div>
  )

And, here is the demo and the completed code for the layout component:
Node: The demo will take sometime for CodeSandbox to start.


import Link from "next/link";
import { useState, memo, useEffect } from "react";
import styles from "./Layout.module.css";

export default function TransitionLayout({ children }) {
  const [displayChildren, setDisplayChildren] = useState(children);
  const [transitionStage, setTransitionStage] = useState("fadeOut");
  useEffect(() => {
    setTransitionStage("fadeIn");
  }, []);

  useEffect(() => {
    if (children !== displayChildren) setTransitionStage("fadeOut");
  }, [children, setDisplayChildren, displayChildren]);

  return (
    <div>
      <nav>
        <Link href="/">Home</Link>
        <Link href="/about">About</Link>
      </nav>
      <div
        onTransitionEnd={() => {
          if (transitionStage === "fadeOut") {
            console.log("fading out");
            setDisplayChildren(children);
            setTransitionStage("fadeIn");
          }
        }}
        className={`${styles.content} ${styles[transitionStage]}`}
      >
        {displayChildren}
      </div>
    </div>
  );
}


Thank you all!!


This content originally appeared on DEV Community and was authored by AnxinYang


Print Share Comment Cite Upload Translate Updates
APA

AnxinYang | Sciencx (2021-04-20T01:08:04+00:00) Page Transition Effect in NextJS. Retrieved from https://www.scien.cx/2021/04/20/page-transition-effect-in-nextjs/

MLA
" » Page Transition Effect in NextJS." AnxinYang | Sciencx - Tuesday April 20, 2021, https://www.scien.cx/2021/04/20/page-transition-effect-in-nextjs/
HARVARD
AnxinYang | Sciencx Tuesday April 20, 2021 » Page Transition Effect in NextJS., viewed ,<https://www.scien.cx/2021/04/20/page-transition-effect-in-nextjs/>
VANCOUVER
AnxinYang | Sciencx - » Page Transition Effect in NextJS. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/04/20/page-transition-effect-in-nextjs/
CHICAGO
" » Page Transition Effect in NextJS." AnxinYang | Sciencx - Accessed . https://www.scien.cx/2021/04/20/page-transition-effect-in-nextjs/
IEEE
" » Page Transition Effect in NextJS." AnxinYang | Sciencx [Online]. Available: https://www.scien.cx/2021/04/20/page-transition-effect-in-nextjs/. [Accessed: ]
rf:citation
» Page Transition Effect in NextJS | AnxinYang | Sciencx | https://www.scien.cx/2021/04/20/page-transition-effect-in-nextjs/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.