TL;DR
この記事では Next.js の useRouter フックの使い方を TypeScript を用いて詳細に説明します。このフックを理解し使いこなすことで、あなたのアプリケーションはよりダイナミックで使いやすくなるでしょう。
開発環境 | バージョン |
---|---|
Next.js | 13.4.3 |
TypeScript | 5.0.4 |
Emotion | 11.11.0 |
React | 18.2.0 |
useRouter フックとは?
useRouter
は Next.js に組み込まれている特別なフックで、ルーティングに関連する情報にアクセスするために使われます。具体的には、現在のページの URL、クエリパラメータ、ルーティングメソッドなどにアクセスできます。
これを使って、Google Analytics を設定したり、問い合わせフォームを送信した後に特定のページにリダイレクトしたりすることができます。
useRouter
は、ウェブサイトの中で移動するための地図のようなものです。例えば、家の中で部屋から部屋へ移動するときに、どの部屋に行くかを知るために地図を使うようなイメージです。
useRouter
を使うと、ウェブサイトのどのページにいるのか、または別のページに移動するときにどの道を通るべきかを知ることができます。それによって、ウェブサイトの中でスムーズに移動することができます。
どのようなときに使うのか?
例えば、どのようなときに使うのか?というと
- フォームの送信後に特定のページにリダイレクトする
- ページの移動が終わったときに Google Analytics のページビューイベントを送信する
- ユーザーが認証されていない場合や特定の条件を満たしていない場合に、ログインページやエラーページにリダイレクトする
- 現在の URL パスを取得し、それを基にパンくずリストを生成する
- アクセス制御や認証
- URL パラメータに基づいて特定の商品や記事を表示する
- 404 ページにリダイレクトする
といった場合に使うことができます。
用語解説
次に、主要な用語を表形式でまとめます。
用語 | 説明 |
---|---|
useRouter | Next.js の機能で、ウェブサイト内での移動を管理するもの |
router object | useRouter が提供するオブジェクトで、現在のページの情報やページ間の移動方法を提供 |
pathname | 現在のページのパス(例:/about) |
query | URL のクエリパラメータ(例:?id=123) |
asPath | ブラウザに表示されるパス |
push | 新しいページに移動するためのメソッド |
replace | 現在のページを新しいページで置き換えるためのメソッド |
back | 前のページに戻るためのメソッド |
reload | 現在のページを再読み込みするためのメソッド |
events | ページの移動が始まったときや終わったときなど、ルーターの状態が変わったときに発生するイベント |
Functions: useRouter | Next.jsに書かれているコードを解説します。
import { useRouter } from 'next/router'
function ActiveLink({ children, href }) {
const router = useRouter()
const style = {
marginRight: 10,
color: router.asPath === href ? 'red' : 'black',
}
const handleClick = (e) => {
e.preventDefault()
router.push(href)
}
return (
<a href={href} onClick={handleClick} style={style}>
{children}
</a>
)
}
export default ActiveLink
このコードは、Next.js のuseRouter
を使ってリンクを作る例です。ActiveLink
という関数は、子要素(children)とリンク先の URL(href)を受け取り、そのリンクを表示します。リンクの色は、現在のページがリンク先と同じであれば赤色、そうでなければ黒色になります。
handleClick
関数は、リンクがクリックされたときに呼び出されます。この関数は、デフォルトのリンクの動作を止めて(e.preventDefault()
)、代わりにrouter.push(href)
を使って新しいページに移動します。これにより、Next.js のページ間移動の機能を利用することができます。
最後に、このActiveLink
関数をデフォルトでエクスポートしています。これにより、他のファイルからこの関数をインポートして使うことができます。
次のコードは、Next.js のuseRouter
フックを使って、ボタンをクリックしたときに特定のページ(この場合は'/about'ページ)に移動する機能を持つコンポーネントを作成しています。
import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/about')}>
Click me
</button>
)
}
const router = useRouter();
は、useRouter
フックを呼び出して、ルーターオブジェクトを取得しています。このルーターオブジェクトを使って、ページ間の移動を制御します。
<button type="button" onClick={() => router.push('/about')}>
は、ボタンを定義しています。このボタンは、クリックされたときにrouter.push('/about')
を実行します。router.push('/about')
は、'/about'ページに移動する命令です。
useRouter フックの使い方
それでは、簡単な useRouter の使用例を見てみましょう。
// ファイル名: pages/index.tsx
import { useRouter } from 'next/router'
type Props = {
text: string
}
const Page = ({ text }: Props) => {
const router = useRouter()
console.log(router.pathname) // 現在のページのパスが表示される
return <div>{text}</div>
}
export default Page
ここでは、useRouter フックを用いて現在のページのパスをコンソールに出力しています。同様に、router.query
を使用することで URL のクエリパラメータにアクセスすることができます。
Link コンポーネントとの違い
Next.js のLink
コンポーネントとuseRouter
フックは、どちらもページ間の移動を制御するためのツールですが、使い方と機能にはいくつか違いがあります。
Link
コンポーネントは、主に静的なリンクを作成するために使用されます。つまり、リンク先の URL が固定で、クリックするだけで特定のページに移動するようなリンクを作るときに使います。Link
コンポーネントは、自動的に<a>
タグを生成し、Next.js のページ間移動の機能を利用します。
一方、useRouter
フックは、より動的なページ間の移動を制御するために使用されます。例えば、ユーザーのアクションに基づいてリンク先を決定したり、プログラム的にページを移動したりするときに使います。useRouter
は、ルーターオブジェクトを提供し、そのオブジェクトのメソッド(push
、replace
など)を使ってページ間の移動を制御します。
先程の例では、ボタンがクリックされたときに特定のページ('/about'ページ)に移動するという動的な動作を制御しています。このような場合、useRouter
のpush
メソッドを使ってページ間の移動を制御することができます。
したがって、Link
コンポーネントとuseRouter
フックの主な違いは、Link
が静的なリンクを作成するのに対し、useRouter
が動的なページ間の移動を制御するために使用されるという点です。
問い合わせフォームを作成
動的な遷移の例として、Next.js で問い合わせフォームを作成し、フォームが送信された後にユーザーを'thanks'ページにリダイレクトする例を書きます。
import { useRouter } from 'next/router'
import { useState } from 'react'
export default function ContactForm() {
const router = useRouter()
const [formData, setFormData] = useState({
name: '',
email: '',
message: '',
})
const handleChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value })
}
const handleSubmit = async (e) => {
e.preventDefault()
// ここでフォームデータをAPIに送信する処理を行います。
// 例: await fetch('/api/contact', { method: 'POST', body: JSON.stringify(formData) });
// フォーム送信後に'thanks'ページにリダイレクトします。
router.push('/thanks')
}
return (
<form onSubmit={handleSubmit}>
<input type="text" name="name" value={formData.name} onChange={handleChange} placeholder="Your Name" required />
<input type="email" name="email" value={formData.email} onChange={handleChange} placeholder="Your Email" required />
<textarea name="message" value={formData.message} onChange={handleChange} placeholder="Your Message" required />
<button type="submit">Submit</button>
</form>
)
}
このコードでは、React のuseState
フックを使ってフォームデータを管理し、useRouter
フックを使ってフォーム送信後のリダイレクトを制御しています。また、各フォームフィールドのonChange
イベントハンドラを使って、ユーザーが入力したデータをformData
ステートに保存しています。
handleSubmit
関数は、フォームが送信されたときに呼び出されます。この関数では、まずe.preventDefault()
を呼び出してフォームのデフォルトの送信動作を止め、次にフォームデータを API に送信する処理を行います。最後に、router.push('/thanks')
を呼び出してユーザーを'thanks'ページにリダイレクトします。
このコードはあくまで一例であり、実際のアプリケーションでは API への送信処理やエラーハンドリングなどを適切に実装する必要があります。