
Reactコンポーネントの基本:関数型とクラス型コンポーネントの徹底解説
2025-08-07Reactの核心概念である「コンポーネント」について、初心者向けに詳細に解説します。コンポーネントはUIを独立した再利用可能な部品に分割するための仕組みで、Reactアプリケーションを構築する基礎ブロックとなります。
コンポーネントとは何か?
コンポーネントの基本概念
コンポーネントはReactアプリケーションを構成する独立したUI部品です。以下の特徴を持ちます:
- 自己完結的:特定の機能や見た目をカプセル化
- 再利用可能:同じコンポーネントを複数箇所で使用可能
- 組み合わせ可能:小さなコンポーネントを組み合わせて複雑なUIを構築
// シンプルなボタンコンポーネントの例
function Button() {
return <button>クリックしてください</button>;
}
コンポーネントの利点
- コードの再利用性向上:同じコンポーネントを複数箇所で使用
- メンテナンス性向上:機能ごとにコードを分割
- 開発効率向上:チームメンバーが別々のコンポーネントを並行開発
- テスト容易性:コンポーネント単位でテスト可能
関数型コンポーネント
関数型コンポーネントの基本
関数型コンポーネントはJavaScriptの関数として定義され、propsを引数として受け取り、React要素を返します。
function Greeting() {
return <h1>こんにちは、Reactの世界へ!</h1>;
}
アロー関数での記述
ES6のアロー関数を使用してより簡潔に記述できます。
const Greeting = () => {
return <h1>こんにちは、Reactの世界へ!</h1>;
};
// 暗黙のreturnを使用すればさらに簡潔に
const Greeting = () => <h1>こんにちは、Reactの世界へ!</h1>;
関数型コンポーネントの特徴
- シンプルな構文:クラスよりも簡潔に記述可能
- パフォーマンス:クラスコンポーネントより軽量
- Hooks対応:React 16.8以降、状態管理も可能に
- 推奨方法:現在のReactでは関数型コンポーネントが主流
実用的な関数型コンポーネントの例
const UserProfile = () => {
const user = {
name: '山田太郎',
age: 28,
hobbies: ['読書', '旅行', '写真']
};
return (
<div className="profile">
<h2>{user.name}</h2>
<p>年齢: {user.age}歳</p>
<h3>趣味:</h3>
<ul>
{user.hobbies.map((hobby, index) => (
<li key={index}>{hobby}</li>
))}
</ul>
</div>
);
};
クラス型コンポーネント
クラス型コンポーネントの基本
クラス型コンポーネントはES6クラスとして定義され、React.Component
を継承します。
import React from 'react';
class Greeting extends React.Component {
render() {
return <h1>こんにちは、Reactの世界へ!</h1>;
}
}
クラス型コンポーネントの構造
クラスコンポーネントにはいくつかの必須要素があります:
- React.Componentの継承
- render()メソッド:必須、React要素を返す
- コンストラクタ(任意):stateの初期化など
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
return (
<div>
<p>現在のカウント: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
増やす
</button>
</div>
);
}
}
クラス型コンポーネントの特徴
- ライフサイクルメソッド:コンポーネントの各段階で処理を実行可能
- state管理:コンポーネント固有の状態を保持
- thisの使用:メソッド内でthisを使用してプロパティやメソッドにアクセス
- 歴史的経緯:以前は状態管理にはクラスが必要だった
関数型とクラス型の比較
構文の違い
特徴 | 関数型コンポーネント | クラス型コンポーネント |
---|---|---|
定義方法 | 関数 | class、extends React.Component |
状態管理 | useState Hook | this.state |
ライフサイクル | useEffect Hook | ライフサイクルメソッド |
thisの使用 | 不要 | 必要 |
コード量 | 少ない | 多い |
使用推奨
現在のReact(バージョン16.8以降)では、関数型コンポーネントとHooksの使用が推奨されています。新規プロジェクトでは関数型コンポーネントを使用するのが良いでしょう。
ただし、既存のコードベースでクラスコンポーネントが使用されている場合や、特定のライブラリがクラスコンポーネントを要求する場合など、クラスコンポーネントの知識も必要です。
コンポーネントの命名規則
コンポーネント名にはパスカルケース(大文字で始まる)を使用します。
// 正しい例
function UserProfile() { /* ... */ }
class ShoppingCart extends React.Component { /* ... */ }
// 誤った例
function userProfile() { /* ... */ }
class shopping_cart extends React.Component { /* ... */ }
この命名規則は重要で、Reactは大文字で始まるコンポーネントをカスタムコンポーネントとして認識します。
コンポーネントの分割のベストプラクティス
いつコンポーネントを分割すべきか?
- UIが複雑になったとき
- 同じUIパターンが繰り返されるとき
- コンポーネントが複数の責務を持っているとき
- 再利用が必要な部分があるとき
分割の例:ユーザーカードコンポーネント
// 分割前のモノリシックなコンポーネント
const UserProfile = () => {
// ...多くのコード...
};
// 分割後のコンポーネント
const UserAvatar = () => { /* ... */ };
const UserInfo = () => { /* ... */ };
const UserHobbies = () => { /* ... */ };
const UserProfile = () => (
<div className="user-profile">
<UserAvatar />
<UserInfo />
<UserHobbies />
</div>
);
コンポーネントの実践例
関数型コンポーネントの実例:Todoアイテム
const TodoItem = ({ task, completed }) => {
return (
<li className={`todo-item ${completed ? 'completed' : ''}`}>
<input type="checkbox" checked={completed} readOnly />
<span>{task}</span>
</li>
);
};
// 使用例
<TodoItem task="Reactを学ぶ" completed={false} />
クラス型コンポーネントの実例:タイマー
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = { seconds: 0 };
}
componentDidMount() {
this.interval = setInterval(() => {
this.setState(prevState => ({
seconds: prevState.seconds + 1
}));
}, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<div>
<p>経過時間: {this.state.seconds}秒</p>
</div>
);
}
}
コンポーネントのファイル構成
プロジェクトが成長するにつれ、コンポーネントを適切に整理することが重要です。
推奨されるファイル構造
src/
components/
Button/
Button.jsx
Button.css
index.js
Header/
Header.jsx
Header.css
index.js
...
index.jsの役割
// src/components/Button/index.js
export { default } from './Button';
これにより、インポート時にディレクトリ名だけでコンポーネントを参照できます。
import Button from './components/Button';
コンポーネント開発のデバッグ技法
よくあるエラーと解決策
- コンポーネントが表示されない:
- コンポーネント名が大文字で始まっているか確認
- エクスポート/インポートが正しいか確認
- TypeError: Cannot read property…:
- thisのバインドを確認(クラスコンポーネント)
- propsの存在を確認
- Unexpected tokenエラー:
- JSX構文の誤りを確認(タグの閉じ忘れなど)
デバッグツール
- React Developer Tools:
- コンポーネント階層を検査
- propsとstateを表示
- コンソールログ:
const MyComponent = (props) => {
console.log('Props:', props);
return <div>...</div>;
};
- デバッガーステートメント:
debugger; // 実行を一時停止
コンポーネント設計のベストプラクティス
- 単一責任の原則:
1つのコンポーネントは1つの役割だけを持つ - 適切な分割:
大きすぎるコンポーネントは分割を検討 - 再利用性:
汎用的なコンポーネントは再利用可能に設計 - 命名の明確化:
コンポーネント名から役割がわかるように - プレゼンテーション/コンテナコンポーネントの分離:
- プレゼンテーション:見た目だけを担当
- コンテナ:データ処理や状態管理を担当
次に学ぶべきこと
コンポーネントの基本を理解したら、次のステップとして以下の概念を学びましょう:
- PropsとStateの管理:
- 親から子コンポーネントへのデータ渡し(Props)
- コンポーネント内部の状態管理(State)
- イベント処理:
- ユーザー操作への対応(onClickなど)
- ライフサイクル:
- コンポーネントのマウント/更新/アンマウント時の処理
- フォーム処理:
- 制御されたコンポーネント(Controlled Components)の実装
コンポーネントはReactの核心概念です。関数型とクラス型の違いを理解し、適切な場面で使い分けられるようにしましょう。最初はシンプルなコンポーネントから始めて、徐々に複雑なものを作成していくのがおすすめです。