この記事はpagesディレクトリのケースで書いています!
はじめに
Next.jsのrouter.push
とrouter.replace
は、アプリケーションのルーティングを行うためのメソッドですが、ブラウザの履歴にどのように影響を与えるかで違いがあるようです。
所属しているチームのプルリクを見ていて理解が曖昧であることに気づいたので、学習のアウトプットとしてまとめます。
router.push
router.push(url, as, options)
- url:String - 移動先の URL
- as:String - ブラウザのURLバーに表示されるパスのデコレータ
- options:
- scroll:boolean - ナビゲーションの後、ページのトップにスクロールすることを制御。(デフォルトはtrueなので、ページの最上部に移動する。)
- shallow:getStaticProps, getServerSideProps, getInitialPropsを再実行せずに現在のページのパスを更新。(デフォルトはfalseなので、getServerSidePropsは再実行される。)
- locale:String - 新しいページのロケールを示す
ユーザーをログインページへリダイレクトする
import { useEffect } from 'react'
import { useRouter } from 'next/router'
// Here you would fetch and return the user
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オブジェクト
next/linkと同じようにURLオブジェクトを使うことができ、パラメータは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.pushの特徴
新たに指定したパスをブラウザの履歴に追加する。
(router.pushを使用してページを変更した後、ユーザーがブラウザの「戻る」ボタンを押すと、元のページに戻る)
router.pushの使用例
-
リストから詳細ページへの遷移
例えば、ある記事リストのページからユーザーが特定の記事をクリックし、その記事の詳細ページに遷移するといったケース。この場合、ユーザーはブラウザの「戻る」ボタンを使って記事リストに戻ることができる。 -
ユーザー認証後のリダイレクト
ユーザーがログインした後、特定のページ(例えばユーザープロフィールページ)にリダイレクトする場合。ユーザーがブラウザの「戻る」ボタンをクリックすると、ログインページに戻ることができる。 -
検索結果の表示
ユーザーが検索クエリを入力し、その結果を表示する新しいページに移動する場合。ユーザーは、必要に応じて「戻る」ボタンで検索フォームに戻ることができる。
router.replace
router.replace(url, as, options)
import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.replace('/home')}>
Click me
</button>
)
}
router.replaceの特徴
現在のページを履歴スタックから新しいページに置き換え、ブラウザの履歴に追加しない。
(「戻る」ボタンを押しても、router.replaceで置き換えた以前のページには戻らない挙動)
router.replaceの使用例
-
リストのフィルタリングやソート
商品リストページでユーザーがフィルタリングやソートを行うようなケース。ユーザーが「戻る」ボタンを押したときに、フィルタリングやソート前の商品リストに戻るのは直感的ではないため、ブラウザの履歴には影響を与えないようにする。 -
ページ内のタブ切り替え
あるページ内で複数のタブ間を切り替える場合、URLにタブの状態を反映させつつ、ブラウザの履歴には追加したくない場合。 -
ページネーション
一覧ページなどでページネーションを行う際、ページ番号をURLのクエリパラメータとして設定することで、ユーザーが直接URLを変更して移動できるようにするもの。各ページ間の遷移で「戻る」ボタンを押したときにページネーションの前の状態に戻るのは直感的でないため。
メモ
appディレクトリではこちらを使うらしい
pages
からapp
への移行は以下のとおり↓