【ITニュース解説】React Router: Navigate on Button Click with createBrowserRouter (TypeScript, Pro Patterns)
2025年09月19日に「Dev.to」が公開したITニュース「React Router: Navigate on Button Click with createBrowserRouter (TypeScript, Pro Patterns)」について初心者にもわかりやすく解説しています。
ITニュース概要
React Router v6.4+でWebアプリの画面遷移を学ぶガイド。ボタンクリックでページを移動するには`useNavigate()`を使い、認証などで事前遷移する場合は`redirect()`をローダー/アクションで使う。`react-router-dom`からインポートし、相対パス活用で保守性を高める。
ITニュース解説
Webアプリケーションにおいて、複数のページ間を行き来することは基本的な機能である。このページ間の移動をスムーズに、かつ効率的に管理するために「ルーティング」という仕組みが使われる。React Routerは、Reactアプリケーションでこのルーティング機能を実現するための非常に強力なライブラリである。特にバージョン6.4以降では、「Data API」と呼ばれる新しい機能が導入され、より洗練された方法でルーティングを扱うことができるようになった。
React Routerを使ってルーティングを設定する最初のステップは、アプリケーションの「ルーター」を定義することである。これにはcreateBrowserRouterという関数が使われる。この関数には、どのURLパスでどのコンポーネントを表示するか、というルールを配列形式で渡す。例えば、/というパスならHomeコンポーネント、/dashboardというパスならDashboardコンポーネント、といった形である。これらのルート定義には、親となるレイアウトコンポーネントの中に子ルートを入れ子にすることもでき、共通のヘッダーやサイドバーを持つページ構成を簡単に実現できる。定義したルーターは、RouterProviderというコンポーネントに渡すことで、Reactアプリケーション全体で利用可能になる。これにより、アプリケーションが起動すると同時にルーティング機能が有効になる。ここで注意すべき重要な点がある。Webブラウザで動作するReactアプリケーションでは、react-router-domというパッケージから必要なものをインポートする必要がある。react-routerというパッケージも存在するが、これはWeb以外の環境(例えばReact Native)で使われる汎用的なものであり、WebアプリケーションのDOM(Document Object Model)操作に関する機能はreact-router-domに含まれているため、誤ってreact-routerからインポートしないよう注意が必要である。
ユーザーがボタンをクリックした時など、特定のイベントが発生した後にページ遷移を行いたい場合、useNavigateという特別な関数(Reactのフックと呼ぶ)が非常に便利である。このuseNavigateをコンポーネント内で呼び出すと、ページを移動させるためのnavigate関数が返される。例えば、navigate('/dashboard')と書けば、アプリケーションは「/dashboard」のパスへ移動する。さらに、navigate関数には、遷移先のページに情報を渡すためのstateオプションも用意されている。これは、ログイン後の「ようこそ!」メッセージや、前のページからの特定のコンテキスト情報を渡したい場合に非常に役立つ。遷移先のコンポーネントでは、useLocationフックを使って、このstateの情報を読み取ることができる。履歴の操作も重要である。デフォルトでは、navigate関数は新しいページへの移動をブラウザの履歴に追加する(「プッシュ」という動作)。そのため、ブラウザの「戻る」ボタンを押すと、元のページに戻ることができる。しかし、ログイン後やログアウト後など、前のページに戻ってほしくない場面では、navigate('/home', { replace: true })のようにreplace: trueオプションを使うことで、現在の履歴エントリを新しいものに置き換えることができる。これにより、ユーザーは「戻る」ボタンを押しても、意図しないページへは戻らなくなる。また、navigate(-1)のように負の数を渡すことで、ブラウザの履歴を一つ戻る操作も可能である。
ページを移動する方法はuseNavigateだけではない。React Routerには用途に応じて複数のナビゲーション手段が提供されている。一つは<Link>コンポーネントである。これはHTMLの<a>タグ(アンカータグ)に似ており、クリックすると別のページへ遷移する。特別なロジックを必要とせず、単に別のページへのリンクを表示したい場合に最適である。アクセシビリティも考慮されており、また、ユーザーがリンクにマウスを重ねた際に、遷移先のページのリソースを事前に読み込む「プリフェッチ」動作を行うことで、実際のクリック時のロード時間を短縮する効果もある。もう一つは、loaderまたはaction内でのredirectである。特定の条件に基づいてページ遷移を事前に決定したい場合、例えば、ユーザーがログインしているかどうかをチェックして、ログインしていなければログインページへリダイレクトする場合などに非常に有効である。loaderはページが表示される前にデータを取得したり、権限をチェックしたりする関数であり、actionはフォームの送信などのデータ更新処理を行う関数である。これらの関数内でredirect('/login')のように呼び出すと、対象のコンポーネントが一度もレンダリングされることなく、指定されたページへ直接リダイレクトされる。これにより、認証されていないコンテンツがちらっと表示されてしまう「UIのちらつき」を防ぎ、ユーザー体験を向上させることができる。
大規模なアプリケーションでは、ルーティングの設定をより柔軟で保守しやすいものにするためのテクニックがある。一つは「相対パス」の利用である。アプリケーションのルートパスからの絶対パス(例: /dashboard)だけでなく、現在のURLからの相対パス(例: dashboardや..)を使ってナビゲートすることも可能である。例えば、/projects/123というパスにいるときにnavigate('settings')とすると、/projects/123/settingsへと移動する。navigate('..')とすれば、親のパスである/projects/123から/projectsへと一つ上の階層に移動できる。これは、ネストされたルートを持つ場合に、コンポーネントが自身の親パスを知る必要がなくなり、より結合度の低い(独立性の高い)コードを書くことにつながる。URLには、特定の情報を渡すためのパラメータ(例: /users/123の123)やクエリ文字列(例: /reports?tab=summaryの?tab=summary)が含まれることがある。これらを動的に生成してナビゲートする場合、テンプレートリテラル(バッククォート`で囲まれた文字列)やURLSearchParamsというWeb標準のオブジェクトを使うと、安全かつ簡単にURLを構築できる。特にURLSearchParamsは、既存のクエリパラメータを読み込み、新しいパラメータを追加・変更して、それらを文字列に変換するのに便利である。
React Routerを使う上で、いくつか注意すべき落とし穴が存在する。前述したように、Webアプリケーションでは必ずreact-router-domからインポートすることを忘れないようにする必要がある。また、useSearchParamsフックで取得したURLSearchParamsオブジェクトを直接変更するのではなく、一度クローン(コピー)を作成してから変更し、そのクローンをsetSearchParamsに渡すようにする必要がある。こうすることで、Reactが変更を正しく検知し、UIが適切に更新される。コンポーネントが描画される前にリダイレクトすべき状況(認証チェックなど)では、loader内でredirect関数を使用するべきである。コンポーネント内でNavigateコンポーネントやuseNavigateを使ってリダイレクトすると、一度コンポーネントがレンダリングされてからリダイレクトが走るため、ユーザーに一瞬不適切な画面が見えてしまう可能性がある。さらに、非同期処理(データ取得など)のコールバック内でnavigateを呼び出す場合、その非同期処理が完了する前にコンポーネントが画面から消えてしまう(アンマウントされる)と、エラーが発生することがある。これを避けるためには、非同期処理をキャンセルする仕組みを導入したり、コンポーネントがまだマウントされているかどうかをチェックするフラグを利用したりするなどの対策が必要である。
ユーザーがフォームを送信した後、例えば「お問い合わせありがとうございます」というページに移動させたい場合、React Routerのaction機能とredirectを組み合わせるのが理想的である。フォームコンポーネントをFormコンポーネントでラップし、method="post"を指定することで、フォームデータは自動的に対応するルートのaction関数に渡される。action関数内でフォームデータを処理し、データベースへの保存などを行った後、redirect('/thanks')を返せば、ユーザーはデータが処理された後に直接指定のサンクスページに遷移する。これにより、サーバーへのリクエストとリダイレクトが連携して行われ、ユーザーはスムーズな体験を得られる。
Reactアプリケーションでのページ遷移は、useNavigate、<Link>、そしてloaderやaction内のredirectを使い分けることで、あらゆる状況に対応できる。特にreact-router-domからのインポートと、複雑なロジックを伴う場合はuseNavigate、描画前の条件分岐にはloaderやaction内のredirectを使うのが、安定したアプリケーションを構築するためのベストプラクティスである。相対パスを上手に活用することで、コードの結合度を低く保ち、メンテナンス性を高めることもできる。これらの機能を適切に理解し活用することで、初心者であっても、堅牢で使いやすいWebアプリケーションを開発できるようになるだろう。