BLOG
ブログ
Next.jsでページ遷移アニメーションを実装する

こんにちは、ZOOANです。
Next.js 13.4の試用を兼ねて、ページ遷移アニメーションを実装してみました。
デモ
「ここをクリック」という部分をクリックするとページ遷移します。
DEMOディレクトリ構成
ディレクトリ構成は以下の通りです。
├─ app
│  │  component-link.tsx
│  │  client-home.tsx
│  │  page.tsx
│  │  
│  └─ test
│          client-test.tsx
│          page.tsx
内容
/app/page.tsx, /app/test/page.tsx
ページファイルなので割愛します。
/app/component-link.tsx
クリック時にアニメーション処理を実行するコンポーネントです。
CSSでtransitionを設定しています。
'use client'
import { useEffect } from 'react'
import { useRouter } from 'next/navigation'
import Link from 'next/link'
type Props = {
  href: string,
  children: React.ReactNode,
}
export const useReset = () => {
  const router = useRouter()
  useEffect(() => {
    const body = document.querySelector('body')!
    body.classList.remove('page-transition-animation')
  }, [router])
}
export default function LinkComponent(props: Props) {
  const router = useRouter()
  const clickEventHandler = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
    e.preventDefault()
    const body = document.querySelector('body')!
    body.classList.add('page-transition-animation')
    setTimeout(() => {
      router.push(props.href)
    }, 1000)
  }
  return (
    <Link href={props.href} onClick={clickEventHandler}>{props.children}</Link>
  )
}
/app/client-home.tsx
component-link.tsxをimportしてtestページへのリンクを設置します。
'use client'
import CmLink from '@/app/component-link'
export default function ClientHome() {
  return (
    <>
      <div className="h-screen flex items-center justify-center">
        <p>Top Page</p>
      </div>
      <div className="h-screen flex items-center justify-center">
        <p>1</p>
      </div>
      <div className="h-screen flex items-center justify-center">
        <CmLink href="/test">2!ここをクリック!</CmLink>
      </div>
      <div className="h-screen flex items-center justify-center">
        <p>3</p>
      </div>
    </>
  )
}
/app/test/client-test.tsx
component-link.tsxのカスタムフックを呼び出して、マウント時にアニメーション処理をリセットします。
'use client'
import { useReset } from '@/app/component-link'
export default function ClientTest() {
  useReset()
  return (
    <>
      <div className="h-screen flex items-center justify-center">
        <p>Test Page</p>
      </div>
      <div className="h-screen flex items-center justify-center">
        <p>1</p>
      </div>
      <div className="h-screen flex items-center justify-center">
        <p>2</p>
      </div>
      <div className="h-screen flex items-center justify-center">
        <p>3</p>
      </div>
    </>
  )
}
以上です。
ちょっとだけでもReactとNext.jsがわかってくると開発が楽しくなってきますね。まだまだわからないことだらけなので、引き続きフロントエンド周りの学習を続けたいと思います。