Masayan tech blog.

  1. ブログ記事一覧>
  2. Next.jsにおけるURLの管理・制御の方法(next/linkとnext/router)

Next.jsにおけるURLの管理・制御の方法(next/linkとnext/router)

公開日

環境

  • windows10
  • node 18.13.0
  • npm 8.19.3
  • TypeScript 4.9.5
  • React 18.2.0
  • Next.js 13.2.1
  • VsCode
  • gitbash 2.32.0.1

next/linkとnext/router

next/link

https://nextjs-ja-translation-docs.vercel.app/docs/api-reference/next/link

  • こちらは、リンク用のコンポーネントを作成するための機能
  • Next.jsにはLinkコンポーネントが用意されているので、propsでURLオブジェクトを渡してあげるだけで、自動的にフォーマットして URL 文字列を作成してくれる。
  • Linkコンポーネントでaタグをラップする

frontend\next-web\src\components\atomic\Atoms\Link\BasicLink.tsx

import React  from 'react'
import Link from 'next/link'

..割愛
const BasicLink = (props) => {
  const { href, name } = props

  return (
    <Link
      href={{
        pathname: href.pathname,
        query: href.query
      }}
    >
      <a>{name}</a>
    </Link>
  )
}

export default BasicLink

frontend\next-web\src\pages\posts\[postId]\index.tsx

  • 呼び出す側でurlオブジェクトを渡すことにより、idやクエリパラメーター等を含む動的なpathも簡単に生成できる
// 以下の例では、 /posts/1/comments/1?category=hoge 等のurlが生成される

<BasicLink
  href={{
    pathname: '/posts/[postId]/comments/[commentId]',
    query: { postId: post.id, commentId: comment.id, category: "hoge" }
  }}
  name={comment.content}
/>

next/router

https://nextjs-ja-translation-docs.vercel.app/docs/api-reference/next/router

  • こちらは、urlを取得・操作するための機能
  • Next.jsにはuseRouterというHooksが用意されているのでこちらを使用する
  • routerオブジェクトを取得したり、ページ遷移の処理を実装することが可能

routerオブジェクトの取得

import { useRouter } from'next/router'

const Sample= () => {
  const router = useRouter()
  console.log(router) // routerオブジェクトが取得できる
  ... 割愛
}

routerオブジェクトに含まれる主な内容

  • asPath: ブラウザに表示される実際のパス(クエリ含む)
    "/posts/1/comments/1?category=hoge" など
  • pathname:現在のルート
    "/posts/[postId]/comments/[commentId]"
  • query:クエリ文字列
    {postId: '1', commentId: '1', category: 'hoge'}
    • queryは、同一urlにおいて複数回指定される可能性があるため、以下のようにstringまたはstring[]として取得されることに注意
      interface ParsedUrlQuery extends NodeJS.Dict<string | string[]> {}

useEffect内で使用する際の注意

router.queryをuseEffectの中で使用する際は、以下のようにする必要がある(Pre-renderingの間はqueryは空のオブジェクトであり、hydrationのプロセスが終わった段階でqueryオブジェクトが提供されるため)

  • 初回レンダリング時にuseEffectが発火したタイミングでは、まだrouter.queryは空のオブジェクト{}であるため、router.isReadyのフラグを使用してあげる必要がある
  • router.isReadyフラグの変更を受けて再度useEffect内の処理を実行するために、必ず依存配列にはrouter.isReadyを含めること(そのほかにも依存している内容があればそれらも併せて指定する)
useEffect(() => {
  if (!router.isReady) return;
  ...何らかの処理
}, [router.isReady])

Router API

  • Router APIを利用して、urlを操作することが可能
ページ遷移
// 事前に定義されたルートへの遷移
router.push('/signin')

// urlオブジェクトを渡して動的なurlへ遷移することも可能

router.push({
  pathname: '/posts/[postId]/comments/[commentId]',
  query: { postId: 1, commentId: 3, category: 'hoge' }
})

※routerは、サイト内のクライアントサイドルーティング用のため、外部URLに対してはwindow.location等を使用して遷移する

1つ前のページに戻る(ブラウザの戻るボタンをクリックするのと同じ)
router.back()
ページリロード
router.reload()
イベントのリッスン

例えば、urlの変更を感知して何か処理を行いたい時などに便利

router.events()

以上です。

まとめ

いかがでしたでしょうか。本記事では、Next.jsにおけるnext/linkとnext/routerを用いたURLの管理・制御の方法について紹介しています。SPAではクライアントサイドナビゲーションが必須になりますがNext.jsではどのように書けば実現できるかについての内容を中心に具体例を交えながら説明しています