結論
大体同じ。でも基本は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を参考にしてみました。
そこで示されたいくつかの意見を一覧にします。
同じだよという意見
- 違いはなくアプローチの仕方が違うだけ。
-
useRouter
はRouterContext
をクラス化しただけ。つまり同じ。
ちょっと違うよという意見
-
useRouter
はクラスコンポーネント内部で使用することはできないという違いがある。 -
Router
は常にその時点の最新のグローバル状態を指すのに対し、useRouter
はレンダリング中のルートを参照するという違いがある
おすすめの書き方に関する意見
react@>=18
の同時実行性などとの互換性を保つために、以下のようにすべき。
- 関数コンポーネントでは
useRouter
を一般的に使用する。(クラスコンポーネントならwithRouter
) -
Router
は、Reactのライフサイクルの外でのみ使用する(例:useEffectやイベントハンドラの中)。
「react@>=18
の同時実行性などとの互換性を保つ」とは?
この点についてさらに説明があったので、自分の理解に噛み砕いてみました。
以下の例を考えてみるとよく分かると思います。
【例】
ユーザーがリンクをクリックした時、
そのページは多くのデータを取得する必要があるためにユーザーが待機させられたとします。
その間に現在のパス名をalert()するボタンをクリックしたとしたらどうなるでしょうか。
遷移前のページがクリックと同時に再レンダリングされます。
useRouter
を使用していると現在のページのURLがalert
で表示されますが、
Router
オブジェクトをしようしていると、遷移後のページのURLが表示されることになります。
このケースであれば『alert()
ボタンを押した時点でのページのURL』が欲しいはずなので、
この場合にはuseRouter
を使っておきたいです。
ただuserRouter
はuseEffect
などのコールバック関数内で呼び出すと以下のようなエラーが出るので、それを避けられないような時には必要に応じて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.
最後に
全然解釈違うよ・間違ってるよというのがあれば教えてもらえると幸いです。