React
Facebookが開発したユーザーインターフェース構築のためのJavaScriptライブラリ。コンポーネントベースの設計により、再利用可能で保守性の高いUIを作成可能。
フレームワーク
React
概要
Reactは、Facebookが開発したユーザーインターフェース構築のためのJavaScriptライブラリです。
詳細
React(リアクト)は2013年にFacebookによってオープンソース化された、宣言的で効率的、かつ柔軟なJavaScriptライブラリです。UIを構築するためのコンポーネントベースアーキテクチャを採用し、再利用可能なUIコンポーネントを作成できます。Virtual DOMという仮想的なDOM表現を使用することで、実際のDOM操作を最小限に抑え、高いパフォーマンスを実現しています。単方向データフローとステート管理により、予測可能で保守しやすいアプリケーション開発が可能です。JSXという拡張構文により、HTMLライクな記述でコンポーネントを定義でき、開発者体験が向上しています。現在では世界最大のフロントエンドエコシステムを持ち、Next.js、Gatsby、React Nativeなど多くの関連技術と組み合わせて使用されています。
メリット・デメリット
メリット
- コンポーネントベース: 再利用可能なUIコンポーネントで保守性向上
- Virtual DOM: 高いパフォーマンスと効率的なレンダリング
- 豊富なエコシステム: 膨大なライブラリとツール群
- 学習コミュニティ: 世界最大級の開発者コミュニティ
- 企業サポート: Meta(Facebook)による継続的な開発とサポート
- TypeScript対応: 型安全性による開発体験の向上
- React DevTools: 優秀な開発・デバッグツール
デメリット
- 学習コスト: JSX、フック、ステート管理など習得項目が多い
- 急速な変化: 頻繁なアップデートとベストプラクティスの変更
- 設定の複雑さ: 本格的なプロジェクトでは多くの設定が必要
- SEOの課題: Client-Side Renderingによる検索エンジン最適化の問題
- バンドルサイズ: 大規模アプリケーションでのバンドルサイズ増大
主要リンク
書き方の例
Hello World
// 関数コンポーネントの基本形
function HelloWorld() {
return <h1>Hello, React!</h1>;
}
// アロー関数での記述
const HelloWorld = () => {
return <h1>Hello, React!</h1>;
}
// レンダリング
import ReactDOM from 'react-dom/client';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<HelloWorld />);
コンポーネントとProps
// Propsを受け取るコンポーネント
function Welcome(props) {
return <h1>こんにちは、{props.name}さん!</h1>;
}
// 分割代入を使った記述
function Welcome({ name, age }) {
return (
<div>
<h1>こんにちは、{name}さん!</h1>
<p>あなたは{age}歳ですね。</p>
</div>
);
}
// 使用例
function App() {
return (
<div>
<Welcome name="太郎" age={25} />
<Welcome name="花子" age={30} />
</div>
);
}
ステート管理(useState)
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
const decrement = () => {
setCount(count - 1);
};
return (
<div>
<h2>カウンター: {count}</h2>
<button onClick={increment}>+1</button>
<button onClick={decrement}>-1</button>
<button onClick={() => setCount(0)}>リセット</button>
</div>
);
}
エフェクト(useEffect)
import { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// データの取得
const fetchUser = async () => {
setLoading(true);
try {
const response = await fetch(`/api/users/${userId}`);
const userData = await response.json();
setUser(userData);
} catch (error) {
console.error('ユーザーデータの取得に失敗:', error);
} finally {
setLoading(false);
}
};
fetchUser();
}, [userId]); // userIdが変更されたときに再実行
if (loading) return <div>読み込み中...</div>;
if (!user) return <div>ユーザーが見つかりません</div>;
return (
<div>
<h2>{user.name}</h2>
<p>メール: {user.email}</p>
</div>
);
}
フォーム処理
import { useState } from 'react';
function ContactForm() {
const [formData, setFormData] = useState({
name: '',
email: '',
message: ''
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({
...prev,
[name]: value
}));
};
const handleSubmit = (e) => {
e.preventDefault();
console.log('送信データ:', formData);
// API送信処理など
};
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="name">名前:</label>
<input
type="text"
id="name"
name="name"
value={formData.name}
onChange={handleChange}
required
/>
</div>
<div>
<label htmlFor="email">メール:</label>
<input
type="email"
id="email"
name="email"
value={formData.email}
onChange={handleChange}
required
/>
</div>
<div>
<label htmlFor="message">メッセージ:</label>
<textarea
id="message"
name="message"
value={formData.message}
onChange={handleChange}
rows={4}
required
/>
</div>
<button type="submit">送信</button>
</form>
);
}
カスタムフック
import { useState, useEffect } from 'react';
// カスタムフック: データフェッチング
function useApi(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const response = await fetch(url);
if (!response.ok) {
throw new Error('データの取得に失敗しました');
}
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
// カスタムフックの使用例
function ProductList() {
const { data: products, loading, error } = useApi('/api/products');
if (loading) return <div>読み込み中...</div>;
if (error) return <div>エラー: {error}</div>;
return (
<ul>
{products?.map(product => (
<li key={product.id}>
{product.name} - {product.price}円
</li>
))}
</ul>
);
}