paint-brush
高度な React Router V6 テクニック: 基本を超えて@sojinsamuel
6,354 測定値
6,354 測定値

高度な React Router V6 テクニック: 基本を超えて

Sojin Samuel11m2023/07/02
Read on Terminal Reader

長すぎる; 読むには

React Router は、React アプリケーションで動的でスムーズなナビゲーションを作成できる素晴らしいツールです。ルーティング能力をまったく新しいレベルに引き上げる、あまり知られていないテクニックがいくつかあります。悪名高い 404 ページの処理について説明します。現在のルートを強調表示するアクティブ ページ インジケーターを作成します。 「useNavigate」フックと「useLocation」フックを利用します。
featured image - 高度な React Router V6 テクニック: 基本を超えて
Sojin Samuel HackerNoon profile picture
0-item
1-item

今日は高度なReact Router テクニックを皆さんと共有できることをとても楽しみにしています。 React Router は、 Reactアプリケーションで動的でスムーズなナビゲーションを作成できる素晴らしいツールです。


これは基本的なルーティングのニーズによく使用されますが、ルーティング能力をまったく新しいレベルに引き上げることができる、あまり知られていないテクニックがいくつかあります。


今日は、私が時間をかけて見つけた私のお気に入りのいくつかを共有します。


以下について説明します。

  1. 悪名高い404ページの処理。
  2. 現在のルートを強調表示するアクティブ ページ インジケーターを作成します。
  3. useNavigateフックとuseLocationフックを使用します。


この記事を読み終える頃には、これらの高度な React Router テクニックをしっかりと理解し、自信を持って自分のプロジェクトに適用できるようになっているでしょう。


それでは、早速本題に取り掛かり、一緒にルーティング スキルを向上させましょう。


準備はできたか?始めましょう!

404 ページの処理


より大きなプロジェクトに取り組むときは、見つからないルートに注意することが不可欠です。これらのルートは、サーバー上でドキュメントが見つからない場合にHTTP ステータス コード404 を返すため、多くの場合404 ルートと呼ばれます。


ちなみに、猫好きの方はhttp.catをチェックしてみるのも楽しいかもしれません。


次に、ブラウザ内の現在の URL に一致する他のルートがない場合にトリガーされる特別なルートの作成に移りましょう。

 import {BrowserRouter, Routes, Route} from "react-router-dom"; function App() { return <BrowserRouter> <Routes> <Route path="/" element={<p>Landing page</p>}></Route> <Route path="/products" element={<p>Products page</p>}></Route> <Route path="*" element={<p>404 page</p>}></Route> </Routes> </BrowserRouter> }

プライマリ ページ/にアクセスすると、ユーザーはランディング ページにリダイレクトされます。 /productsページに移動すると、Products ページに移動します。ただし、特定のルートに対応しない他のリンクにアクセスすると、404 ページが表示されます。


この動作の背後にある理由は、パス プロパティが*に設定されている、404 ページ用の特殊な<Route>の実装です。この構成により、他に一致するルートがない場合に、React Router がこのルートを排他的に利用するようになります。 404 Route の具体的な配置は重要ではなく、その不可欠なコンポーネントとして<Routes>...</Routes>セクション内のどこにでも配置できます。

アクティブなページ

アプリがルートを実際に利用できるもう 1 つの方法は、メニュー内で現在アクティブなページを強調表示することです。


2 つのリンクがあるナビゲーション メニューがあると想像してみましょう。


  1. ホーム - このリンクにより、ユーザーはメイン ページ/に移動します。

  2. About - このリンクにより、ユーザーは about ページ/aboutに移動します。


React Router を使用すると、ユーザーが/aboutルート上にいるときにAboutリンクを自動的にハイライト表示できるようになります。同様に、ユーザーが/ルート上にいるときにホーム リンクを強調表示できます。最も良い点は、複雑な条件を必要とせずにこれを実現できることです。


これを機能させる簡単な方法は次のとおりです。

 import {NavLink} from "react-router-dom"; function getClassName({isActive}) { if (isActive) { return "active"; // CSS class } } function App() { return <ul> <li> <NavLink to="/" className={getClassName}>Home</NavLink> </li> <li> <NavLink to="/about" className={getClassName}>About</NavLink> </li> </ul> }


上記のコードは、 activeクラスを機能させるためにいくつかの CSS を必要とします。したがって、現在アクティブなページのメニュー リンクを太字で目立つようにすることで、機能を強化できます。

 .active { font-weight: bold; }


NavLink要素のclassName属性には、単なる文字列ではなく関数を受け入れる柔軟性があります。関数を使用することに決めた場合、関数にはパラメータとしてオブジェクトが与えられ、このオブジェクトにはisActiveプロパティがすでに設定されています。関数内でこのプロパティに簡単にアクセスするには、パラメーターに{isActive}を含めて構造化を使用します。


次に、 isActive正しい値を保持しているかどうかの検証に進みます。その場合は、 CSSクラス名activeを返します。


React Router の現在のパスがNavLinkコンポーネントのto属性と一致する場合、 isActive関数はブール値に評価されます。


その結果、React Router はactiveクラスを対応する<NavLink />要素にシームレスに組み込み、それが現在アクティブなルートであることを示します。

短いバージョン

より短いアプローチを希望する場合は、三項演算子を使用して上記のコードをリファクタリングできます。この演算子は、次の形式を使用して if/else ステートメントを置き換える方法を提供しますcondition ? truthy expression : falsy expression

三項演算子はコードが読みにくくなることが多いため、実際にはあまり使用しません。ただし、この場合は使用しても問題ありません。


例として次のことを考えてみましょう。

 function getClassName({isActive}) { if (isActive) { return "active"; } else { return ""; } }


上記のコードを次のアプローチに置き換えることができます。

 function getClassName({isActive}) { return isActive ? "active" : ""; }


return ステートメントが三項演算子の外側に配置されていることを確認するだけで済みます。 isActive条件が true の場合、 ?以降の式は"active"で実行されます。それ以外の場合は、 :の後の式が""実行されます。


これで、 getClassNameと呼ばれる別の関数定義の必要性を排除できます。代わりに、次のようなアロー関数を使用できます: ({isActive}) => isActive ? "active" : ""


この変更がわかりにくい場合は、以前と同様に別の関数を使用し続けることができます。

最終的なコードは次のようになります。

 import {NavLink} from "react-router-dom"; function App() { return <ul> <li> <NavLink to="/" className={({isActive}) => isActive ? "active" : ""}>Home</NavLink> </li> <li> <NavLink to="/about" className={({isActive}) => isActive ? "active" : ""}>About</NavLink> </li> </ul> }

ああ、あなたの意見はよくわかります。

ソジンさん、DRY原則を破ってしまいましたよね?

これはほんの一例です。気を引き締める必要はありません 😀

Link と NavLink の選択: 両者の違いは何ですか?

すでにお気づきかもしれませんが、私はいつもの友人であるLinkの代わりにNavLinkを使用しています。でも心配しないでください、その理由を説明しましょう。 <Link />コンポーネントでは、 classNameプロパティの関数定義を使用できません。そうですね、驚くかもしれませんが、 <Link />を操作するときはまさにそのような感じです。


私がこれまでに見たよくある間違いの 1 つは、若手 React 開発者が<Link />コンポーネントのclassNameプロパティで関数定義を使用しようとしたことですが、これはまったく機能しません。


ご興味があれば、このトピックについて記事を書きます。コメント欄でお知らせください!

useNavigate

特定の状況では、React アプリケーション内のページをプログラムで再配置する必要がある場合があります。たとえば、訪問者を特定のページにリダイレクトするには、リクエストを送信して応答を待つことができます。


以下にいくつかの例を示します。

  • ユーザーがサインインしていない場合は、ログイン ページに送信します。
  • getLogin リクエストが正常に完了したら、ユーザーを/dashboardにリダイレクトします。


これには、 useNavigate()フックを使用する必要があります。このフックは、プログラムでユーザーを新しいルートにリダイレクトするために使用できる関数を返します。


ご覧ください:

 import React, {useEffect} from "react"; import {useNavigate} from "react-router-dom"; function HelpPage() { const navigate = useNavigate(); useEffect(() => { const isLoggedIn = window.localStorage.getItem("isLoggedIn"); if (!isLoggedIn) { navigate("/login"); } }, []); return <h2>Help page</h2>; }

BrowserRouter の使用は必須です。

この例では、 localStorage にキーisLoggedInに割り当てられた値があるかどうかを確認しています。そうでない場合は、 navigate("/login")関数を使用してユーザーを/loginページにリダイレクトします。


これを機能させるには、 <BrowserRouter />コンポーネント内にネストされているコンポーネント内でuseNavigate()フックを使用することを忘れないでください。そうしないと、正しく機能しません。


たとえば、次の例は機能しません。

 import React from "react"; import {BrowserRouter, useNavigate} from "react-router-dom"; function App() { // ❌ This breaks because the component was not wrapped by BrowserRouter, but its children are. const history = useNavigate(); return <BrowserRouter> {/* ... */} </BrowserRouter>; }

App()コンポーネント内でuseNavigate()フックを使用しようとすると、少し問題が発生する可能性があります。これは、 App()コンポーネントを<BrowserRouter />でラップしない限り機能しないためです。


でも心配しないでください。


良いニュースは、App 内のすべての子コンポーネントが<BrowserRouter />によって自動的にラップされるため、これらの子コンポーネントでuseNavigate()を問題なく使用できることです。


ただし、本当に<App />コンポーネント自体でuseNavigate()を使用する必要がある場合は、簡単な解決策があります。 <App />をラップする親コンポーネントを作成し、その親コンポーネント内に<BrowserRouter />を移動するだけです。これを完了したら、 <App />コンポーネントでuseNavigate()を思う存分使用できるようになります 💗

アクセシビリティと適切なリンク使用の確保

Web サイトをアクセシブルにする場合、リンクの構造に注意を払うことが重要です。これを確実に行うには、他のメソッドではなく<Link />要素を使用することをお勧めします。


なぜ?


これらの要素は、アクセシビリティ機能で知られる<a>タグとして自動的にレンダリングされます。

さて、ここでフレンドリーなヒントを紹介します。通常の<Link />要素をuseNavigate()が提供する.push()メソッドに置き換えることは避けてください。このメソッドは<Link />要素を使用できない場合にのみ使用してください。


それはいつ起こりますか?

通常、これは、 fetch()操作の結果など、特定のロジックに基づいてプログラムでユーザーをリダイレクトする必要がある場合です。

使用場所

React Router が新しいアドレスに移動するたびにコードを実行したい場合はどうすればよいでしょうか?

useLocationフックを使用すると、これを簡単に実現できます。詳細に入る前に、これが役立ついくつかのシナリオを検討してみましょう。最も一般的な使用例の 1 つは、Google Analytics などの分析サービスにページビューイベントを送信することです。


ただし、Google アナリティクス 4 ではこれが自動的に処理されるため、必ずしも自分で実装する必要はないことに注意してください。


それでも、 useLocationフックについて学ぶことは、他の用途が見つかる可能性があるため、依然として価値があります。たとえば、これを使用して他のライブラリや分析サービスと統合したり、訪問ルートに基づいて特定のアクションを実行したりできます。


可能性は無限大!

useLocation フック

useLocationフックは、現在使用されているルートに関する情報を提供するため、非常に便利です。


useLocation フックの使用方法に関するわかりやすいガイドは次のとおりです。

 import {BrowserRouter, Routes, Route, useLocation} from "react-router-dom"; import {createRoot} from "react-dom/client"; function App() { const location = useLocation(); console.log(location.pathname); return <Routes> {/* routes here... */} </Routes> } createRoot(document.querySelector("#react-root")).render(<BrowserRouter><App /></BrowserRouter>);


これで、location 変数を介してルート情報にアクセスできるようになりました。これは、現在のpathnameを含むオブジェクトです。


ユーザーが現在どのルートを参照しているかを確認するには、 location.pathname使用するだけです。 //about 、または設定したその他のルートのようなものが表示されます。


useNavigateフックと同様に、 <BrowserRouter />でラップされたコンポーネント内でコードを実行することが重要であることに注意してください。そうしないと、 useLocationフックはその魔法を発揮できません。

場所の変更への対応

場所が変更された場合、 useLocationフックを使用して React Router の現在の URL パスにアクセスできます。コードをuseEffectフックでラップし、依存関係をlocationに設定すると、新しい URL へのナビゲーションがあるたびに特定のコード部分を実行できます。


その方法の例を次に示します。

 import React, {useEffect} from "react"; import {BrowserRouter, Routes, Route, useLocation} from "react-router-dom"; import {createRoot} from "react-dom/client"; function App() { const location = useLocation(); // run a piece of code on location change useEffect(() => { console.log(location.pathname); // send it to analytic, or do some conditional logic here }, [location]); return <Routes> {/* routes here... */} </Routes> } createRoot(document.querySelector("#react-root")).render(<BrowserRouter><App /></BrowserRouter>);

ユーザーがナビゲーション中に新しいルートに移動するたびに、 useEffectフック内のコードが実行され、その処理が行われます。これは基本的に、場所オブジェクトに変更があるたびに特定のコードが確実に実行されるようにする方法です。

よかったです。これであなたも React Router エキスパート 🥳

結論として、この記事では React Router についてより深く理解することができました。ただし、ここで説明したすべての機能を使用できるわけではありません。それでも、あなたがそれらを認識していることは素晴らしいことです。将来、同様の機能を組み込む必要がある場合でも、どこを調べればよいかがわかります。したがって、簡単に参照できるように、必ずこの投稿を保存またはブックマークしてください。ご質問がある場合、またはさらにサポートが必要な場合は、お気軽に Twitter までご連絡ください。私は助けに来ました!