概要: 本記事では、Reactアプリ開発に不可欠なコンポーネント、Props、Hooksといった基本要素を分かりやすく解説します。さらに、Context APIによる効率的な状態管理や、React Routerを使ったルーティングについても触れ、React開発の全体像を掴めるように構成しました。
React開発の基本:コンポーネント、Props、Hooksを徹底解説
React Appの基本構造とコンポーネントの役割
機能コンポーネントとクラスコンポーネントの違い
Reactは、ユーザーインターフェースを構築するためのJavaScriptライブラリであり、その根幹をなすのが「コンポーネント」です。コンポーネントは、UIの独立した再利用可能な部品であり、アプリケーションのUIを構築する上での基本的なブロックとなります。これらはJavaScriptの関数、あるいはクラスとして定義され、それぞれがUIの一部を記述する役割を担います。(出典: 参考情報「コンポーネント (Components)」)
初期のReactでは、状態管理やライフサイクルメソッドを扱うために「クラスコンポーネント」が主流でした。これらはReact.Componentを継承して定義され、render()メソッド内でUIを返します。 しかし、ES6のクラス構文の学習コストや、thisのバインディング問題といった課題も存在しました。
一方で、「機能コンポーネント」は単なるJavaScript関数として定義され、Propsと呼ばれる入力を受け取り、React要素を返します。React 16.8でHooksが導入されて以降、機能コンポーネントでも状態(state)や副作用(side effects)といったクラスコンポーネントでしか扱えなかった機能を扱えるようになり、その人気は爆発的に高まりました。現在では、新規開発においては機能コンポーネントとHooksの使用が強く推奨されています。 これはコードの簡潔さ、可読性の向上、そして再利用性の高さから来ています。コンポーネントの名前は常に大文字で始める必要があり、小文字で始めるとReactはそれをDOMタグとして解釈するという点も重要です。(出典: 参考情報「機能コンポーネント(Function Components)」、「クラスコンポーネント(Class Components)」)
コンポーネントの合成と抽出による開発効率化
React開発の大きな強みの一つは、コンポーネントの「合成 (Composing Components)」と「抽出 (Extracting Components)」です。コンポーネントは、他のコンポーネントをその出力内で参照することで、より複雑なUIを構築できます。例えば、一つの大きなAppコンポーネントの中に、ヘッダー、サイドバー、メインコンテンツといった複数の独立したコンポーネントを配置し、それぞれがさらに小さなコンポーネントを内包するといった階層的な構造が一般的です。(出典: 参考情報「コンポーネントの合成 (Composing Components)」)
この合成の概念により、開発者はUIを抽象化のレベルを問わず、同じコンポーネント抽象化を利用して構築することが可能になります。例えば、ボタンコンポーネントがアイコンコンポーネントとテキストコンポーネントを合成して作られるといった具合です。
さらに、複雑になりがちなコンポーネントを「抽出 (Extracting Components)」して、より小さく、管理しやすい部分に分割することは、メンテナンス性と再利用性を大幅に向上させます。例えば、ユーザーのプロフィール表示を行うコンポーネントが、アバター画像、ユーザー名、詳細情報といった複数の要素を含んでいる場合、これらをそれぞれ独立したAvatar、UserName、UserDetailsなどのコンポーネントとして抽出すれば、コードの見通しが良くなり、個々の部品を別の場所で再利用しやすくなります。このアプローチは、アプリケーションの変更容易性とスケーラビリティを高める上で不可欠なプラクティスです。(出典: 参考情報「コンポーネントの抽出 (Extracting Components)」)
Reactの組み込みコンポーネントの活用
Reactには、開発をより効率的かつ柔軟に進めるためのいくつかの「組み込みコンポーネント」が存在します。これらはJSX内で直接使用でき、特定の目的のために設計されています。代表的なものとしては、<Fragment>、<Profiler>、<Suspense>、<StrictMode>が挙げられます。(出典: 参考情報「組み込みコンポーネント (Built-in Components)」)
<Fragment>(または省略形の<>...</>)は、複数のJSXノードをグループ化する際に非常に便利です。Reactコンポーネントは一つの親要素しか返せないという制約がありますが、<Fragment>を使えば余計なDOMノードを追加することなく、複数の要素をまとめることができます。これにより、HTML構造をシンプルに保ちながら、コンポーネントの要件を満たすことが可能です。
<Profiler>は、アプリケーションのパフォーマンス測定に特化したコンポーネントです。Reactツリーのレンダリングパフォーマンスをプログラムで測定し、ボトルネックの特定や最適化に役立ちます。開発段階で特に有用です。
<Suspense>は、子コンポーネントのロード中にフォールバックUIを表示するために使用されます。非同期データフェッチやコード分割と組み合わせて使うことで、ユーザー体験を向上させることができます。例えば、データの読み込みが完了するまでローディングスピナーを表示するといった処理を簡潔に実装できます。
最後に、<StrictMode>は、開発時のみ有効になる追加のチェック機能を提供し、潜在的なバグを早期に発見するのに役立ちます。例えば、非推奨のライフサイクルメソッドの使用や、意図しない副作用の検出などが可能です。本番環境では無効になるため、開発の安全性と品質を高めるために積極的に活用すべきコンポーネントです。(出典: 参考情報「組み込みコンポーネント (Built-in Components)」)
Propsとは?Reactコンポーネント間でデータを渡す方法
Propsの基本と役割
Reactコンポーネントは独立した再利用可能な部品ですが、それらが連携して一つのアプリケーションを形成するためには、互いにデータをやり取りする必要があります。このデータ伝達の仕組みが「Props(プロパティ)」です。Propsは、親コンポーネントから子コンポーネントへ情報を渡すための手段であり、Reactアプリケーションにおけるデータの流れを理解する上で非常に重要な概念です。(出典: 参考情報「Props (Properties)」)
Propsは、HTML要素の属性に似ています。例えば、<img src="image.jpg" alt="Description" /> のsrcやaltが属性であるように、Reactコンポーネントに対しても同様の形式でデータを渡します。しかし、HTML属性が主に文字列値を扱うのに対し、Propsはオブジェクト、配列、関数、数値、真偽値など、あらゆるJavaScriptの値を渡すことができます。 これにより、非常に柔軟なデータ連携が可能となります。
例えば、<Greeting name="Alice" message="Hello" />という形でPropsを渡すと、Greetingコンポーネント内でnameとmessageというデータを受け取って利用することができます。この仕組みによって、コンポーネントは自身の内部状態を持たずに、親から与えられたデータに基づいて表示や振る舞いを決定できるため、再利用性が高まり、アプリケーションの構造がシンプルに保たれます。Propsを通じてコンポーネントの多様なバリエーションを表現することができ、例えば同じボタンコンポーネントでも、渡すPropsによって色やテキスト、クリック時の挙動を変えるといった柔軟な設計が可能になります。(出典: 参考情報「Props (Properties)」)
Propsの読み取り専用特性と命名規則
Propsを扱う上で最も重要なルールの一つが、「Propsは読み取り専用(Props are Read-Only)」であるという原則です。これは、子コンポーネントが受け取ったPropsの値を直接変更してはならないことを意味します。もし子コンポーネントがPropsの値を変更してしまうと、親コンポーネントの意図しないデータの変更が発生し、アプリケーションの状態管理が複雑化し、デバッグが困難になる可能性があります。この一方向のデータフローは「単一方向データフロー(Unidirectional Data Flow)」と呼ばれ、Reactの予測可能な挙動を保証する基盤となっています。(出典: 参考情報「Propsは読み取り専用(Props are Read-Only)」)
インタラクティブな機能、つまりコンポーネント自身の内部でデータを変更する必要がある場合は、Propsではなく「State(状態)」を使用する必要があります。Stateはコンポーネント内部で管理される可変のデータであり、後述するHooksのuseStateを通じて扱います。Propsは親から子へ渡される不変のデータ、Stateはコンポーネント自身が管理する可変のデータと理解すると良いでしょう。
Propsの命名については、コンポーネントの観点から意味のある名前を付けることが推奨されています。例えば、ユーザーのプロフィールを表示するコンポーネントに、ユーザーの名前を渡す場合はuserName、画像を渡す場合はavatarUrlのように、そのPropsがコンポーネント内でどのように使われるかを明確に示す名前が望ましいです。これにより、コードの可読性が向上し、他の開発者がコンポーネントのインターフェースを理解しやすくなります。(出典: 参考情報「Propsの命名」)
Propsのデフォルト値と具体的な利用例
Reactでは、Propsが渡されなかった場合に備えて、「デフォルト値」を設定することが可能です。これにより、親コンポーネントが特定のPropsを渡すのを忘れてしまった場合や、オプションのPropsである場合に、予期せぬエラーやUIの崩れを防ぐことができます。デフォルト値は、機能コンポーネントの場合、関数の引数で直接指定したり、古いReactではdefaultProps静的プロパティを使用したりしていました。(出典: 参考情報「Propsのデフォルト値」)
例えば、以下のようなButtonコンポーネントを考えてみましょう。
// 機能コンポーネントでのPropsのデフォルト値の例
function Button({ text = "Click Me", color = "blue" }) {
return (
<button style={{ backgroundColor: color, color: 'white', padding: '10px 20px', border: 'none', borderRadius: '5px' }}>
{text}
</button>
);
}
// 使用例:
// <Button /> -> "Click Me"というテキストと青色のボタン
// <Button text="Submit" /> -> "Submit"というテキストと青色のボタン
// <Button text="Cancel" color="red" /> -> "Cancel"というテキストと赤色のボタン
この例では、text Propsにデフォルトで”Click Me”が、color Propsには”blue”が設定されています。これにより、Propsが何も渡されなくてもボタンは正常に表示されます。また、特定のPropsだけを上書きして、一部のデフォルト値を活用することも可能です。
このようにPropsのデフォルト値を活用することで、コンポーネントの柔軟性を高めつつ、堅牢性を保つことができます。特に、再利用性の高い汎用コンポーネントを作成する際には、デフォルト値の設定は非常に有用なプラクティスとなります。(出典: 参考情報「Props (Properties)」を基に作成)
React Hooks入門:状態管理や副作用処理を効率化
useStateによるコンポーネントの状態管理
React 16.8で導入された「Hooks」は、機能コンポーネント内で状態(State)やライフサイクル機能など、これまでクラスコンポーネントでしか扱えなかったReactの機能を簡単に利用できるようにした画期的な機能です。中でも、最も頻繁に使用されるHooksの一つがuseStateです。(出典: 参考情報「Hooks」)
useStateは、機能コンポーネントに状態を追加するために使われます。状態とは、コンポーネントが保持するデータであり、時間の経過とともに変化したり、ユーザーの操作によって更新されたりするものです。useStateを呼び出すと、現在の状態値と、その状態を更新するための関数のペアが返されます。
基本的な使い方は非常にシンプルです。例えば、カウント数を管理する状態を作成するには、const [count, setCount] = useState(0);のように記述します。ここで、countが現在の状態値、setCountが状態を更新する関数、0が初期状態値です。setCountを呼び出して新しい値を渡すと、Reactはそのコンポーネントを再レンダリングし、新しいcount値が反映されます。
状態更新の注意点として、現在の状態と同じ値で状態を更新しようとすると、ReactはObject.is比較アルゴリズムを使用してレンダリングをスキップし、パフォーマンスを最適化します。また、新しい状態が前の状態値に依存する場合(例: カウンターをインクリメントする)、setCountに直接新しい値を渡すのではなく、更新関数を渡すことが推奨されます。例えば、setCount(prevCount => prevCount + 1);のように記述することで、非同期な状態更新による意図しない結果を防ぐことができます。(出典: 参考情報「`useState`」)
useEffectによるコンポーネントの副作用処理
useEffectは、コンポーネントのレンダリング後に、外部システム(ネットワークリクエスト、DOM操作、タイマー設定、イベントリスナーの追加など)と連携・同期するための「副作用(side effects)」を実行するために使用されるHookです。クラスコンポーネントのcomponentDidMount、componentDidUpdate、componentWillUnmountといったライフサイクルメソッドの役割を、一つの統一されたAPIで提供します。(出典: 参考情報「`useEffect`」)
useEffectは関数の引数を2つ取ります。一つ目は副作用のロジックを含む関数、二つ目は依存配列です。依存配列を空の配列[]にすると、コンポーネントがマウントされた時(初回レンダリング後)に一度だけ実行され、アンマウント時にクリーンアップ処理が実行されます。これはcomponentDidMountとcomponentWillUnmountに相当します。
依存配列に特定の変数を渡すと、その変数が変更されるたびに副作用が再実行されます。これはcomponentDidUpdateに相当する動作です。依存配列を省略すると、コンポーネントのレンダリングごとに副作用が実行されます。
例えば、ドキュメントのタイトルを更新する、外部APIからデータをフェッチする、タイマーを設定するといった処理がuseEffectの典型的な使用例です。副作用が実行される前にクリーンアップが必要な場合(例: イベントリスナーの削除、タイマーのクリア)、useEffectが返す関数内でその処理を記述します。これにより、メモリリークや意図しない動作を防ぎ、リソースを適切に管理することができます。クリーンアップ関数は、コンポーネントがアンマウントされる前や、依存配列が変更されて副作用が再実行される前に呼び出されます。(出典: 参考情報「`useEffect`」)
その他の主要なHooksとカスタムHooksの活用
useStateとuseEffectの他にも、Reactは強力な組み込みHooksを提供しています。その中でも特に重要なのがuseContextとuseRefです。(出典: 参考情報「主な組み込みHooks」)
useContextは、親コンポーネントから深くネストされた子コンポーネントまで、Propsをバケツリレーのように手渡すことなく、直接情報を受け取れるようにするHookです。例えば、アプリケーション全体のUIテーマやユーザー認証情報を、最上位コンポーネントからすべての子孫コンポーネントに提供したい場合に非常に有効です。これにより、Propsの記述が大幅に削減され、コードが簡潔になります。
useRefは、DOMノードへの直接的な参照(Ref)や、レンダリングには使用されないがコンポーネントのライフサイクル全体で保持したい可変の値(例: タイマーID、直前の値など)を保持するために使用されます。useStateとは異なり、useRefで保持する値を更新してもコンポーネントは再レンダリングされません。これは、UIの更新をトリガーせずに、特定の値を「保持」したい場合に便利です。
さらに、React開発では「カスタムHooks」も重要な役割を果たします。カスタムHooksは、機能コンポーネント間で状態管理ロジックを再利用可能にするための規約のようなJavaScript関数です。関数名の先頭がuseで始まるというルールがあり、これに従うことで、例えばフォームの入力値管理や特定のAPIフェッチロジックなどを、複数のコンポーネントで共有できるようになります。これにより、コードの重複が減り、保守性が向上します。
Hooksを利用する際には、「トップレベルでのみHookを呼び出す」(ループ、条件分岐、ネストされた関数内では呼び出さない)と「React機能コンポーネントからのみHookを呼び出す」(通常のJavaScript関数からは呼び出せない、カスタムHook内を除く)という二つのルールを厳守することが重要です。これらのルールを守ることで、ReactはHooksの内部状態を正しく管理し、予測可能な動作を保証します。(出典: 参考情報「Hooksのルール」)
Context APIによるグローバルな状態管理とProviderの活用
Context APIの必要性と基本
Reactアプリケーションが大規模になると、多くのコンポーネント間で共有されるデータ(例: 認証情報、UIテーマ、言語設定など)が増えてきます。これらのデータをPropsとして親から子へ、そしてさらにその子へと深くネストされたコンポーネントチェーンを通じて手渡ししていく方法は、「Propsバケツリレー」と呼ばれ、コードの可読性やメンテナンス性を著しく低下させます。このような課題を解決するために導入されたのが「Context API」です。(出典: 参考情報「useContext」および一般知識)
Context APIは、コンポーネントツリー内の任意のレベルにあるコンポーネントが、Propsを明示的に渡すことなく、特定のデータにアクセスできるようにする仕組みです。これにより、グローバルな状態を効率的に管理し、アプリケーション全体で共有する必要があるデータを簡単に配布できるようになります。Context APIの基本的なアイデアは、特定の「Context(コンテキスト)」を作成し、そのContextに値を「Provider(プロバイダー)」を通して供給し、コンポーネントツリーの下流でその値を「Consumer(コンシューマー)」として受け取るというものです。
この仕組みにより、特定のデータが必要なコンポーネントだけがそのデータにアクセスできるようになり、中間にある無関係なコンポーネントはPropsの受け渡しに関与する必要がなくなります。結果として、コードがよりクリーンで、理解しやすくなり、変更にも強くなります。大規模なアプリケーションにおける状態管理戦略を検討する上で、Context APIは非常に強力なツールとなります。
createContextとProviderの役割
Context APIを利用するための最初のステップは、React.createContext()を使ってContextオブジェクトを作成することです。この関数は、コンテキストオブジェクトを返します。このオブジェクトには、ProviderとConsumerという2つのReactコンポーネントが含まれています。
// Contextオブジェクトの作成例
const ThemeContext = React.createContext('light'); // 初期値として'light'を設定
次に、Contextに実際に値を供給するのが「Provider」コンポーネントの役割です。Providerは、その子コンポーネントツリー全体にContextの値を供給します。ProviderコンポーネントはvalueというPropsを受け取り、このvalueに渡されたデータが、そのProvider配下のすべてのコンポーネントで利用可能になります。
// Providerの使用例
function App() {
const theme = 'dark'; // あるいは状態から取得
return (
<ThemeContext.Provider value={theme}>
<Toolbar /> {/* Toolbarとその子孫コンポーネントはthemeにアクセスできる */}
</ThemeContext.Provider>
);
}
Providerは、アプリケーションの任意の場所に配置できます。通常は、アプリケーション全体で共有したい値であれば、ルートコンポーネント(例: Appコンポーネント)の近くに配置することが多いです。また、複数のProviderをネストして使用することも可能で、これにより複数の異なるコンテキストをアプリケーションの異なる部分で提供することができます。ProviderのvaluePropsが変更されると、そのProvider配下のContextを消費しているすべてのコンポーネントが再レンダリングされます。これは、Contextの変更が下流のコンポーネントに伝播するメカニズムです。(出典: 一般知識)
useContext Hookによる値の取得
機能コンポーネント内でContextの値を消費する最も現代的で推奨される方法は、useContext Hookを使用することです。このHookは、特定のContextオブジェクトを引数として受け取り、そのContextの現在の値を返します。これにより、クラスコンポーネントでContext.Consumerコンポーネントをレンダープロップス形式で使用するよりも、はるかに簡潔にContextの値を扱えるようになります。(出典: 参考情報「`useContext`」)
例えば、前のセクションで作成したThemeContextからテーマの値を取得するには、以下のように記述します。
// useContextの使用例
import React, { useContext } from 'react';
// import { ThemeContext } from './path/to/ThemeContext'; // ThemeContextをインポート
function ThemedButton() {
const theme = useContext(ThemeContext); // ThemeContextの現在の値を取得
return (
<button style={{ backgroundColor: theme === 'dark' ? 'black' : 'white', color: theme === 'dark' ? 'white' : 'black' }}>
現在のテーマ: {theme}
</button>
);
}
このように、useContext(ThemeContext)を呼び出すだけで、ThemeContext.Providerが提供している現在のテーマの値(例: ‘dark’)を直接ThemedButtonコンポーネント内で利用できます。ThemedButtonがコンポーネントツリーのどこに配置されていても、親コンポーネントからPropsとしてテーマを渡す必要はありません。
useContextは、Contextの変更に対して自動的にコンポーネントを再レンダリングするため、グローバルな状態の変更がアプリケーションのUIに即座に反映されます。ただし、Context APIは大規模な状態管理ソリューションの代替として設計されたものではなく、主に特定の値をアプリケーション全体に配布するための軽量な手段として使われるべきです。より複雑なグローバル状態管理には、ReduxやZustandなどのライブラリも検討する価値があります。しかし、シンプルなグローバル状態共有であれば、useContextとuseStateを組み合わせることで十分に対応可能です。(出典: 参考情報「`useContext`」および一般知識)
React RouterとOutletを使ったルーティングの基本
React Routerの役割とSPAにおける重要性
現代のWebアプリケーションでは、ページ遷移時にブラウザ全体をリロードすることなく、動的にコンテンツを切り替える「シングルページアプリケーション(SPA)」が主流となっています。しかし、SPAにおいてURLと表示されるコンテンツを同期させるためには、クライアントサイドでのルーティング機能が不可欠です。ここで登場するのが、Reactアプリケーションでルーティング機能を提供するデファクトスタンダードである「React Router」です。(出典: 一般知識)
React Routerは、ブラウザのURL履歴とReactコンポーネントのマッピングを管理し、URLの変化に応じて適切なコンポーネントをレンダリングする役割を担います。これにより、ユーザーはブラウザの「戻る」ボタンや「進む」ボタンを利用でき、特定のURLをブックマークすることも可能になります。また、サーバーサイドでのルーティングとは異なり、クライアント側で高速なページ遷移を実現し、よりスムーズなユーザー体験を提供します。
React Routerを導入することで、アプリケーションのURL構造を明確にし、異なるページコンテンツへのアクセスを直感的に行えるようになります。例えば、/usersというURLではユーザー一覧コンポーネントを、/users/123というURLではIDが123のユーザー詳細コンポーネントを表示するといったことが可能になります。これにより、Webサイトとしての基本的なナビゲーション機能がReactアプリケーションに統合され、より完全なWeb体験を提供することができます。
ルーティングの基本構成と要素
React Routerを使ったルーティングの基本構成は、主に以下の要素で成り立っています。
-
<BrowserRouter>: アプリケーション全体を囲む最上位のルーターコンポーネントです。HTML5 History APIを利用してURLとUIを同期させます。SPAのルーティングには必須のコンポーネントです。 -
<Routes>: 複数の<Route>コンポーネントをグループ化する役割を持ちます。その中にある<Route>の中から、現在のURLに最も一致するものを一つだけ選択してレンダリングします。 -
<Route>: 特定のURLパスと、そのパスが一致したときにレンダリングするコンポーネントを定義します。主にpathとelementという2つのPropsを受け取ります。-
path: URLのパスパターンを定義します。例えば、/about、/users/:idなどのパスを指定します。:idのようにコロンで始まる部分は、URLパラメータとして動的な値を受け取ることができます。 -
element:pathが現在のURLと一致した場合にレンダリングされるReact要素(コンポーネント)を指定します。
-
これらの要素を組み合わせることで、以下のような基本的なルーティング設定が可能です。
// 基本的なルーティング設定例
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
import UserProfilePage from './pages/UserProfilePage';
import NotFoundPage from './pages/NotFoundPage';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/about" element={<AboutPage />} />
<Route path="/users/:id" element={<UserProfilePage />} />
<Route path="*" element={<NotFoundPage />} /> {/* マッチしないパスの処理 */}
</Routes>
</BrowserRouter>
);
}
この設定により、URLが/ならHomePageが、/aboutならAboutPageが、/users/123ならUserProfilePageがレンダリングされ、それ以外のパスであればNotFoundPageが表示されるようになります。*パスは、定義されたどのパスにも一致しない場合にフォールバックとして使用されます。(出典: 一般知識)
Outletを使ったネストされたルーティング
React Routerでは、より複雑なUIレイアウトや、共通の親要素を持つ複数の子ルートを扱うために、「ネストされたルーティング」の概念が導入されています。そして、このネストされたルーティングにおいて中心的な役割を果たすのが<Outlet>コンポーネントです。(出典: 一般知識)
<Outlet>は、親ルートコンポーネント内で、その子ルートがレンダリングされる場所を指定するためのプレースホルダーとして機能します。例えば、管理画面のように、サイドバーやヘッダーが共通で、メインコンテンツ部分だけがURLによって切り替わるようなレイアウトを考えてみましょう。
// ネストされたルーティングとOutletの例
// レイアウトコンポーネント (例: DashboardLayout.js)
function DashboardLayout() {
return (
<div>
<nav>
<ul>
<li><Link to="profile">プロフィール</Link></li>
<li><Link to="settings">設定</Link></li>
</ul>
</nav>
<main>
<Outlet /> {/* ここに子ルートのコンポーネントがレンダリングされる */}
</main>
</div>
);
}
// ルーティング設定 (例: App.js)
import { BrowserRouter, Routes, Route, Link, Outlet } from 'react-router-dom';
// ...他のコンポーネントのインポート
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/dashboard" element={<DashboardLayout />}>
<Route path="profile" element={<ProfilePage />} /> {/* /dashboard/profile */}
<Route path="settings" element={<SettingsPage />} /> {/* /dashboard/settings */}
<Route index element={<DashboardOverview />} /> {/* /dashboard のデフォルト表示 */}
</Route>
{/* ...他のルート */}
</Routes>
</BrowserRouter>
);
}
この例では、/dashboardという親ルートにDashboardLayoutコンポーネントが割り当てられています。そのDashboardLayoutコンポーネントの内部に<Outlet />を配置することで、/dashboard/profileにアクセスした際にはProfilePageが、/dashboard/settingsにアクセスした際にはSettingsPageが、DashboardLayout内の<main>タグの中にレンダリングされるようになります。index属性を持つ<Route>は、親ルートのパス(この場合は/dashboard)にアクセスしたときのデフォルト表示を定義します。
Outletを使うことで、共通のレイアウト要素を持つ複数のページを効率的に管理し、コードの重複を避けながら複雑なUIフローを構築することができます。これにより、コンポーネントの再利用性が高まり、アプリケーションの構造がより整理されます。また、ネストされたルーティングは、アプリケーションの拡張性も向上させ、新しいサブページを追加する際の作業を容易にします。(出典: 一般知識)
まとめ
よくある質問
Q: React Componentとは何ですか?
A: React Componentは、UIを再利用可能な部品に分割するためのJavaScriptの関数またはクラスです。それぞれが独立したロジックとUIを持ち、組み合わせて複雑な画面を構築します。
Q: React Propsの渡し方にはどのような方法がありますか?
A: Propsは親コンポーネントから子コンポーネントへデータを渡すための仕組みです。子コンポーネントのタグ内に属性として記述することで渡すことができます。例えば、“ のように渡します。
Q: React Hooksとは何ですか?
A: React Hooksは、関数コンポーネントでstate(状態)やライフサイクル機能などのReactの機能を使えるようにする関数群です。useState, useEffectなどが代表的です。
Q: React Context APIはどのような場面で役立ちますか?
A: Context APIは、コンポーネントツリーのどこからでもアクセスできるグローバルな状態を管理したい場合に役立ちます。Propsのバケツリレーを避けるのに効果的です。
Q: React RouterのOutletは何をしますか?
A: React RouterのOutletは、ネストされたルートのコンポーネントを表示する場所を示すコンポーネントです。これにより、親ルートと子ルートでUIを階層的に表示できます。