2
1

More than 1 year has passed since last update.

Next.jsのRouterとuseRouterは何が違うのか

Last updated at Posted at 2021-12-17

結論

大体同じ。でも基本はuseRouterを使う方がベター。

useRouter vs Router

画面遷移する時や、URLパスを取得したい時など利用するuseRouter
以下のように使うことができます。

import { useRouter } from 'next/router';

const router = useRouter();
router.push('/home'); // '/home'へ遷移

同じくRouterというものもあり、オブジェクトも画面遷移やURLパスの取得にも使えます。

import Router from 'next/router';

Router.push('/home');  // '/home'へ遷移

何が違うのか...。
公式ドキュメントを見てもその違いが分からなかったのでちょっと調べてみました。

若干の違い一覧

Nextのリポジトリで行われていたDiscussionを参考にしてみました。
そこで示されたいくつかの意見を一覧にします。

同じだよという意見
- 違いはなくアプローチの仕方が違うだけ。
- useRouterRouterContextをクラス化しただけ。つまり同じ。

ちょっと違うよという意見
- useRouterはクラスコンポーネント内部で使用することはできないという違いがある。
- Routerは常にその時点の最新のグローバル状態を指すのに対し、useRouterはレンダリング中のルートを参照するという違いがある

おすすめの書き方に関する意見
react@>=18の同時実行性などとの互換性を保つために、以下のようにすべき。
- 関数コンポーネントではuseRouterを一般的に使用する。(クラスコンポーネントならwithRouter
- Routerは、Reactのライフサイクルの外でのみ使用する(例:useEffectやイベントハンドラの中)。

react@>=18の同時実行性などとの互換性を保つ」とは?

この点についてさらに説明があったので、自分の理解に噛み砕いてみました。
以下の例を考えてみるとよく分かると思います。

【例】
ユーザーがリンクをクリックした時
そのページは多くのデータを取得する必要があるためにユーザーが待機させられたとします。
その間に現在のパス名をalert()するボタンをクリックしたとしたらどうなるでしょうか。

遷移前のページがクリックと同時に再レンダリングされます。
useRouterを使用していると現在のページのURLがalertで表示されますが、
Routerオブジェクトをしようしていると、遷移後のページのURLが表示されることになります。

このケースであれば『alert()ボタンを押した時点でのページのURL』が欲しいはずなので、
この場合にはuseRouterを使っておきたいです。
ただuserRouteruseEffectなどのコールバック関数内で呼び出すと以下のようなエラーが出るので、それを避けられないような時には必要に応じてRouterオブジェクトを使えば良いということみたいですね。

React Hook "useRouter" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function.

最後に

全然解釈違うよ・間違ってるよというのがあれば教えてもらえると幸いです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1