この記事について
Next.jsの router オブジェクトに存在するメソッドの router.push
と router.replace
が似ていて、どちらを使用するのがベストなのか分からなくなる場面があった為、それぞれの違いと最適な使い道についてNext.jsの実装を参考にしながらまとめました。
router.push
構文
router.push(url, as, options)
できること
指定したリンクにぺージ遷移ができます。
型
router.push
の返り値の型はPromise
で、ジェネリクスで渡している型はboolean
です。
push(url: Url, as?: Url, options?: TransitionOptions): Promise<boolean>;
使用例
import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/home')}>
Click me
</button>
)
}
向いている使い方
- プロジェクト内でページ遷移したいとき
- ドキュメントによると外部リンクを指定する場合は、
window.location
を使うと良いとの記述がありました-
router.push
で外部リンクを指定しても、内部の実装ではwindow.location.href
で遷移する処置を書いていたので使用しても問題なさそうです(該当コード)
-
router.push外部URLに使用する必要はありません。
window.locationは、これらの場合に適しています。
https://nextjs.org/docs/api-reference/next/router
router.replace
構文
router.replace(url, as, options)
できること
指定したリンクにぺージ遷移ができます。
router.push
との違いは、指定したURLをhistoryのスタックに追加せずに上書きしてページ遷移する点です。
NextはURLのhistoryをwindow.history
で管理していますが、router.replace
は直接historyを上書きする感じで実装されていそうでした(該当コード)
型
router.replace
の返り値の型はPromise
で、ジェネリクスで渡している型はboolean
です。
router.push
の型と同一です。
replace(url: Url, as?: Url, options?: TransitionOptions): Promise<boolean>;
使用例
import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.replace('/home')}>
Click me
</button>
)
}
向いている使い方
- ユーザに無効なURLにアクセスされた場合に、指定ページにリダイレクトするとき(
/400
、/500
等)
向いてる場面の例
仕様:ログインしないと閲覧できないページ(/profile/detail
)があり、ログインしていない状態でアクセスされたら/400
に遷移させる
pushの場合だとこうなります
「/profile/detail」 にアクセス → 「/400」 にリダイレクト
history: [/profile/detail, 400]
結果
/400
からブラウザバックすると/profile/detail
に戻れる
replaceの場合だとこうなります
「/profile/detail」 にアクセス → 「/400」 にリダイレクト
history: [400]
結果
historyが上書きされるので/400
からブラウザバックできない
まとめ
- 基本ページ遷移には
router.push
を使用するで問題ない - アクセス制限したいページがあり、リダイレクト処理を行う場合は
router.replace
が向いている
おまけ
-
router.back
はwindow.history.back
と全く同じ(該当コード) -
router.reload
はwindow.location.reload
と全く同じ(該当コード) -
Nextはスクロール位置を
sessionStorage
に保存してそう(該当コード)
localStorage に保存されたデータに期限がないのに対して、sessionStorage に保存されたデータはページのセッションが終了するときに消去されます。
ページのセッションはブラウザを開いている限り、ページの再読み込みや復元を越えて持続します。参考: MDN
不明だった事
-
router.push
やrouter.replace
などのメソッドがPromise
を返している理由が不明でした。どなたかご存知の方いたら教えてくださると嬉しいです!!