リンクとナビゲーション
Next.js ルーターを使用すると、シングルページアプリケーションと同様に、ページ間でクライアントサイドルート遷移を行うことができます。
このクライアントサイドルート遷移を行うために、Link
というReactコンポーネントが提供されています。
import Link from 'next/link'
function Home() {
return (
<ul>
<li>
<Link href="/">Home</Link>
</li>
<li>
<Link href="/about">About Us</Link>
</li>
<li>
<Link href="/blog/hello-world">Blog Post</Link>
</li>
</ul>
)
}
export default Home
上記の例では複数のリンクを使用しています。各リンクはパス(href
)を既知のページにマッピングします
/
→pages/index.js
/about
→pages/about.js
/blog/hello-world
→pages/blog/[slug].js
ビューポート内にあるすべての <Link />
(初期表示またはスクロールによる表示) は、静的生成を使用するページの場合、デフォルトでプリフェッチされます (対応するデータも含む)。サーバーレンダリングされたルートの対応するデータは、<Link />
がクリックされたときにのみフェッチされます。
動的パスへのリンク
パスを作成するために補間を使用することもできます。これは動的ルートセグメントに役立ちます。例えば、プロップとしてコンポーネントに渡された投稿のリストを表示するには
import Link from 'next/link'
function Posts({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link href={`/blog/${encodeURIComponent(post.slug)}`}>
{post.title}
</Link>
</li>
))}
</ul>
)
}
export default Posts
この例では、パスをUTF-8互換に保つために
encodeURIComponent
が使用されています。
あるいは、URLオブジェクトを使用する
import Link from 'next/link'
function Posts({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link
href={{
pathname: '/blog/[slug]',
query: { slug: post.slug },
}}
>
{post.title}
</Link>
</li>
))}
</ul>
)
}
export default Posts
パスを作成するために補間を使用する代わりに、href
でURLオブジェクトを使用します。ここで
pathname
はpages
ディレクトリ内のページ名です。この場合は/blog/[slug]
です。query
は動的セグメントを含むオブジェクトです。この場合はslug
です。
ルーターの注入
Reactコンポーネントでrouter
オブジェクトにアクセスするには、useRouter
またはwithRouter
を使用できます。
一般的に、useRouter
を使用することをお勧めします。
命令型ルーティング
next/link
はほとんどのルーティング要件をカバーできるはずですが、それを使用せずにクライアントサイドナビゲーションを行うこともできます。next/router
のドキュメントをご覧ください。
次の例は、useRouter
を使用した基本的なページナビゲーションの方法を示しています。
import { useRouter } from 'next/router'
export default function ReadMore() {
const router = useRouter()
return (
<button onClick={() => router.push('/about')}>
Click here to read more
</button>
)
}
シャロールーティング
シャロールーティングを使用すると、getServerSideProps
、getStaticProps
、およびgetInitialProps
を含むデータフェッチメソッドを再度実行することなく、URLを変更できます。
状態を失うことなく、useRouter
またはwithRouter
によって追加されたrouter
オブジェクトを介して、更新されたpathname
とquery
を受け取ります。
シャロールーティングを有効にするには、shallow
オプションをtrue
に設定します。次の例を考慮してください
import { useEffect } from 'react'
import { useRouter } from 'next/router'
// Current URL is '/'
function Page() {
const router = useRouter()
useEffect(() => {
// Always do navigations after the first render
router.push('/?counter=10', undefined, { shallow: true })
}, [])
useEffect(() => {
// The counter changed!
}, [router.query.counter])
}
export default Page
URLは/?counter=10
に更新され、ページは置き換えられず、ルートの状態のみが変更されます。
以下に示すように、componentDidUpdate
を介してURLの変更を監視することもできます。
componentDidUpdate(prevProps) {
const { pathname, query } = this.props.router
// verify props have changed to avoid an infinite loop
if (query.counter !== prevProps.router.query.counter) {
// fetch data based on the new query
}
}
注意点
シャロールーティングは、現在のページでのURL変更にのみ機能します。例えば、pages/about.js
という別のページがあり、これを実行すると
router.push('/?counter=10', '/about?counter=10', { shallow: true })
それは新しいページであるため、現在のページをアンロードし、新しいページをロードして、シャロールーティングを要求したとしてもデータフェッチを待ちます。
シャロールーティングがミドルウェアと併用される場合、以前ミドルウェアなしで行われたように、新しいページが現在のページと一致することを保証しません。これは、ミドルウェアが動的に書き換えを行うことができ、シャローでスキップされるデータフェッチなしではクライアント側で検証できないため、シャローなルート変更は常にシャローとして扱われる必要があります。
これは役に立ちましたか?