【Next.js和訳】API Reference/ next/router
この記事について
この記事は、next/routerの記事を和訳したものです。
記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。
next/router
useRouter
アプリ内の任意の関数コンポーネントでrouter
オブジェクトにアクセスしたい場合は、useRouter
フックを使用できます。
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
router
オブジェクト
useRouter
とwithRouter
の両方から返されるrouter
オブジェクトの定義を以下に示します。
-
pathname
:String
- 現在のルート。これは、/pages
にあるページのパスで、設定されたbasePath
やlocale
は含まれません。 -
query
:Object
- オブジェクトに解析されたクエリ文字列です。ページにデータ取得の要件がない場合、プリレンダリング中は空のオブジェクトになります。デフォルトは {} です。 -
asPath
:String
- 設定された basePath やロケールを除いた、ブラウザに表示されるパス(クエリを含む)です。 -
isFallback
:boolean
- 現在のページがフォールバックモードであるかどうかです。 -
basePath
:String
- アクティブな basePath(有効な場合)です。 -
locale
:String
- 有効なロケール(有効な場合) -
locales
:String[]
- サポートされているすべてのロケールです (有効な場合)。 -
defaultLocale
:String
- 現在のデフォルトのロケールです (有効な場合)。 -
domainLocales
:Array<{domain, defaultLocale, locales}>
- 構成されたすべてのドメインロケールです。 -
isReady
:boolean
- ルーターのフィールドがクライアントサイドで更新され、使用可能かどうかを示します。useEffect メソッドの中でのみ使用されるべきで、サーバー上で条件付きでレンダリングするためではありません。 -
isPreview
:boolean
- アプリケーションが現在プレビューモードにあるかどうか。
さらに、以下のメソッドもルータの内部に含まれています。
また、以下の方法もrouter
内に含まれています。
router.push
クライアントサイドのトランジションを処理します。このメソッドは、next/link
だけでは不十分な場合に便利です。
router.push(url, as, options)
-
url
- 遷移先の URL -
as
- ブラウザに表示される URL のオプションのデコレーターです。Next.js 9.5.3 より前のバージョンでは、このデコレーターはダイナミックルートに使用されていましたが、その仕組みについては以前のドキュメントをご覧ください。 -
options
- オプションのオブジェクトで、以下の設定オプションがあります。-
scroll
- オプションのブール値で、ナビゲーション後にページの先頭にスクロールするかどうかを制御します。デフォルトは true です。 -
shallow
-getStaticProps
,getServerSideProps
,getInitialProps
を再実行せずに、現在のページのパスを更新します。既定はfalse
です。
-
-
locale
- オプションの文字列,新しいページのロケールを示します
使用方法
定義済みのルートであるpages/about.js
に移動します。
import { useRouter } from "next/router"
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push("/about")}>
Click me
</button>
)
}
動的なルートである pages/post/[pid].js
をナビゲートしています。
import { useRouter } from "next/router"
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push("/post/abc")}>
Click me
</button>
)
}
ユーザーを pages/login.js
にリダイレクトします。これは、認証の背後にあるページに便利です。
import { useEffect } from "react"
import { useRouter } from "next/router"
// ここでは、ユーザーを取得して返します。
const useUser = () => ({ user: null, loading: false })
export default function Page() {
const { user, loading } = useUser()
const router = useRouter()
useEffect(() => {
if (!(user || loading)) {
router.push("/login")
}
}, [user, loading])
return <p>Redirecting...</p>
}
URL オブジェクトの使用
URL オブジェクトは、next/link
と同じように使うことができます。url
と as
パラメータの両方で動作します。
import { useRouter } from "next/router"
export default function ReadMore({ post }) {
const router = useRouter()
return (
<button
type="button"
onClick={() => {
router.push({
pathname: "/post/[pid]",
query: { pid: post.id },
})
}}
>
Click here to read more
</button>
)
}
router.replace
next/link
の replace
prop と同様に、router.replace
は履歴スタックに新しい URL エントリを追加するのを防ぎます。
router.replace(url, as, options)
-
router.replace
の API は、router.push
の API と全く同じです。
使用方法
以下の例を見てみましょう。
import { useRouter } from "next/router"
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.replace("/home")}>
Click me
</button>
)
}
router.prefetch
クライアント側の遷移を高速化するために、ページをプリフェッチします。このメソッドは、next/link
のないナビゲーションでのみ有効です。next/link
はページのプリフェッチを自動的に行うからです。
router.prefetch(url, as)
-
url
- プリフェッチする URL、つまり一致するページがあるパスです。 -
as
- url 用のオプションのデコレーターです。Next.js 9.5.3 以前では、ダイナミックルートのプリフェッチに使用されていました。過去のドキュメントでは、どのように動作したかを確認できます。
使い方
例えば、ログインページがあり、ログイン後にユーザーをダッシュボードにリダイレクトするとします。この場合、以下の例のようにダッシュボードをプリフェッチすることで、より高速に遷移させることができます。
import { useCallback, useEffect } from "react"
import { useRouter } from "next/router"
export default function Login() {
const router = useRouter()
const handleSubmit = useCallback((e) => {
e.preventDefault()
fetch("/api/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
/* フォームデータ */
}),
}).then((res) => {
// 既にプリフェッチされているダッシュボードページにクライアントサイドで高速に移行する
if (res.ok) router.push("/dashboard")
})
}, [])
useEffect(() => {
// ダッシュボードページのプリフェッチ
router.prefetch("/dashboard")
}, [])
return (
<form onSubmit={handleSubmit}>
{/* フォームフィールド */}
<button type="submit">Login</button>
</form>
)
}
router.beforePopState
場合によっては(例えば、カスタム・サーバを使用している場合など)、popstate を聞いて、ルータがそれを処理する前に何かを行いたいことがあります。
router.beforePopState(cb)
-
cb
- 入力される popstate イベントに対して実行される関数です。この関数は、イベントの状態を次のようなプロップを持つオブジェクトとして受け取ります。-
url
:String
- 新しい状態のためのルートです。これは通常、ページの名前です。 -
as
:String
- ブラウザに表示される URL です。 -
options
:Object
- router.push によって送られる追加オプション
-
cb
が false
を返した場合、Next.js のルーターは popstate
を処理しませんので、その場合はあなたが処理することになります。ファイルシステムのルーティングを無効にするを参照してください。
使用方法
beforePopState
を使って、次の例のようにリクエストを操作したり、SSR の更新を強制したりすることができます。
import { useEffect } from "react"
import { useRouter } from "next/router"
export default function Page() {
const router = useRouter()
useEffect(() => {
router.beforePopState(({ url, as, options }) => {
// 私はこの2つのルートだけを許可したいのです。
if (as !== "/" && as !== "/other") {
// SSRが悪いルートを404として表示する。
window.location.href = as
return false
}
return true
})
}, [])
return <p>Welcome to the page</p>
}
router.back
履歴をさかのぼることができます。ブラウザの「戻る」ボタンをクリックするのと同じです。window.history.back()
が実行されます。
使用方法
import { useRouter } from "next/router"
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.back()}>
Click here to go back
</button>
)
}
router.reload
現在の URL を再読み込みします。ブラウザの更新ボタンをクリックするのと同じです。window.location.reload()が実行されます。
使用方法
import { useRouter } from "next/router"
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.reload()}>
Click here to reload
</button>
)
}
router.events
Next.js Router の内部で発生するさまざまなイベントを聞くことができます。サポートされているイベントのリストは以下の通りです。
-
routeChangeStart(url, { shallow })
- ルートが変更され始めたときに発生します。 -
routeChangeComplete(url, { shallow })
- ルートが完全に変更されたときに実行されます。 -
routeChangeError(err, url, { shallow })
- ルートの変更時にエラーが発生したとき、またはルートのロードがキャンセルされたときに発生します。-
err.cancelled
- ナビゲーションがキャンセルされたかどうかを示します。
-
-
beforeHistoryChange(url, { shallow })
- ブラウザの履歴を変更する前に発生します。 -
hashChangeStart(url, { shallow })
- ハッシュは変更されるが、ページは変更されない場合に発生します。 -
hashChangeComplete(url, { shallow })
- ハッシュが変更されたが、ページが変更されていない場合に発生します。
使い方
例えば、ルーターイベント routeChangeStart
をリッスンするには、pages/_app.js
を開くか作成し、以下のようにイベントを購読します。
import { useEffect } from "react"
import { useRouter } from "next/router"
export default function MyApp({ Component, pageProps }) {
const router = useRouter()
useEffect(() => {
const handleRouteChange = (url, { shallow }) => {
console.log(`App is changing to ${url} ${shallow ? "with" : "without"} shallow routing`)
}
router.events.on("routeChangeStart", handleRouteChange)
// コンポーネントがアンマウントされた場合、アンサブスクライブ
// イベントから `off` メソッドで脱退します。
return () => {
router.events.off("routeChangeStart", handleRouteChange)
}
}, [])
return <Component {...pageProps} />
}
ルーターイベントは、コンポーネントがマウントされたとき(useEffect
または componentDidMount
/ componentWillUnmount
)、またはイベントが発生したときに必須で登録する必要があります。
ルートのロードがキャンセルされた場合(例えば、2 つのリンクを連続して素早くクリックした場合など)、routeChangeError
が発生します。そして、渡された err
には、次の例のように、cancelled
プロパティが true
に設定されます。
import { useEffect } from "react"
import { useRouter } from "next/router"
export default function MyApp({ Component, pageProps }) {
const router = useRouter()
useEffect(() => {
const handleRouteChangeError = (err, url) => {
if (err.cancelled) {
console.log(`Route to ${url} was cancelled!`)
}
}
router.events.on("routeChangeError", handleRouteChangeError)
// コンポーネントがアンマウントされた場合、アンサブスクライブ
// イベントから `off` メソッドで脱退します。
return () => {
router.events.off("routeChangeError", handleRouteChangeError)
}
}, [])
return <Component {...pageProps} />
}
withRouter
useRouter
が最適でない場合、withRouter
でも同じrouter オブジェクトを任意のコンポーネントに追加することができます。
使用方法
import { withRouter } from "next/router"
function Page({ router }) {
return <p>{router.pathname}</p>
}
export default withRouter(Page)
TypeScript
クラスコンポーネントを withRouter
で使用するには、コンポーネントがルーターの prop を受け入れる必要があります。
mport React from 'react'
import { withRouter, NextRouter } from 'next/router'
interface WithRouterProps {
router: NextRouter
}
interface MyComponentProps extends WithRouterProps {}
class MyComponent extends React.Component<MyComponentProps> {
render() {
return <p>{this.props.router.pathname}</p>
}
}
export default withRouter(MyComponent)
Discussion