0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Next.js】useRouterの関数の違いと適切な使い分け(push, replace, back)

Posted at

はじめに

Next.js 15のApp Routerでは、useRouterフック(next/navigationからインポート)を使用してプログラムによるページナビゲーションを実現できます。しかし、pushreplacebackrefreshなど複数のメソッドがあり、どの場面でどれを使うべきか迷うことがあります。

本記事では、それぞれの関数の違いと適切な使い分けについて、実践的なコード例とともに解説します。

結論

先に結論を言っておくと

  • エラーハンドリングでは基本的にreplaceを使用
  • 通常のナビゲーションではpushを使用

です。

useRouterの基本的な使い方

まず、基本的な使い方を確認します。
App Routerではnext/navigationからインポートし、Client Componentで使用します。

"use client";

import { useRouter } from 'next/navigation';

export default function NavigationExample() {
  const router = useRouter();

  return (
    <div>
      <button onClick={() => router.push('/about')}>
        Aboutページへ
      </button>
    </div>
  );
}

各関数の詳細と使い分け

1. router.push(href)

動作

新しいページをブラウザ履歴スタックに追加

特徴

戻るボタンで前のページに戻ることができる

// 基本的な使用法
router.push('/devices');

// クエリパラメータ付き
router.push('/devices?status=active');

// オブジェクト形式(推奨しない - 文字列推奨)
router.push({
  pathname: '/devices',
  query: { status: 'active' }
});

// スクロール制御
router.push('/dashboard', { scroll: false });

使用場面

  • 通常のページ遷移
  • ユーザーが戻る可能性のあるナビゲーション
  • 詳細ページや一覧ページへの遷移

2. router.replace(href)

動作

現在のページを新しいページで置き換え

特徴

戻るボタンで置き換え前のページには戻れない

// エラー時のリダイレクト
if (isError) {
  router.replace('/dealers'); // エラーページに戻れない
}

// ログイン成功後
if (loginSuccess) {
  router.replace('/dashboard'); // ログインページに戻れない
}

// 無効なIDの場合
if (!isValidId) {
  router.replace('/not-found');
}

使用場面

  • エラー時のリダイレクト
  • 認証後のリダイレクト
  • 無効なURLからの修正
  • フォーム送信完了後の遷移

3. router.back()

動作

ブラウザ履歴の1つ前に戻る

特徴

window.history.back()と同等

// キャンセルボタン
const handleCancel = () => {
  router.back();
};

// モーダルの閉じるボタン
const handleCloseModal = () => {
  router.back();
};

使用場面

  • キャンセルボタンの実装
  • モーダルの閉じる処理
  • 戻るボタンの実装

4. router.forward()

動作

ブラウザ履歴の1つ後に進む

特徴

window.history.forward()と同等(使用頻度は低い)

// 進むボタン(カスタムナビゲーション)
const handleForward = () => {
  router.forward();
};

5. router.refresh()

動作

現在のページを再読み込み

特徴

Server Componentsの再実行を行う

// データ更新後の再読み込み
const handleUpdate = async () => {
  await updateData();
  router.refresh(); // Server Componentsを再実行
};

// 手動リフレッシュボタン
const handleRefresh = () => {
  router.refresh();
};

使用場面

  • データ更新後のページ再読み込み
  • キャッシュをクリアしたい場合
  • Server Componentsを再実行したい場合

実践的な使い分け例

エラーハンドリングでの使い分け

export const DealerShowContainer = () => {
  const router = useRouter();
  const params = useParams();
  const dealerId = Number(params.id);

  // 無効なID → replace(戻らせない)
  useEffect(() => {
    if (Number.isNaN(dealerId) || dealerId <= 0) {
      toast.error("無効な販売店IDです");
      router.replace("/dealers"); // ❌ pushだと無効なページに戻れてしまう
    }
  }, [dealerId, router]);

  // APIエラー → replace(エラーページに戻らせない)
  const { data, isError } = useDealerShow({
    onError: () => {
      toast.error("データの取得に失敗しました");
      router.replace("/dealers"); // ❌ pushだとエラーページに戻れてしまう
    }
  });

  // 編集ページへの遷移 → push(通常のナビゲーション)
  const handleEdit = () => {
    router.push(`/dealers/${dealerId}/edit`); // ✅ 戻れるようにする
  };

  return (
    <div>
      <button onClick={handleEdit}>編集</button>
    </div>
  );
};

フォーム処理での使い分け

export const CreateForm = () => {
  const router = useRouter();

  const handleSubmit = async (data: FormData) => {
    try {
      await createDealer(data);
      // 作成成功 → replace(フォームに戻らせない)
      router.replace('/dealers?created=true');
    } catch (error) {
      // エラー時はそのまま(フォームを表示し続ける)
      toast.error("作成に失敗しました");
    }
  };

  const handleCancel = () => {
    // キャンセル → back(前のページに戻る)
    router.back();
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* フォーム内容 */}
      <button type="button" onClick={handleCancel}>
        キャンセル
      </button>
      <button type="submit">作成</button>
    </form>
  );
};

まとめ

  • push
    • 通常のページ遷移(戻れる)
  • replace
    • エラー時、認証後、無効状態からのリダイレクト(戻れない)
  • back
    • 前のページに戻る
  • refresh
    • ページの再読み込み

エラーハンドリングでは基本的にreplaceを使用し、ユーザーがエラー状態のページに戻れないようにするのがベストプラクティスです。通常のナビゲーションではpushを使用し、ユーザーが期待する戻るボタンの動作を保持しましょう。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?