初心者向け:JSX入門ガイド
Reactを学ぶときに避けて通れないのが JSX (JavaScript XML) です。この記事では、初心者でも理解しやすいように、JSXの基礎から利点、使い方、HTMLとの違いまでを詳しく解説します。
1. JSXとは?
JSXは JavaScriptの中でHTMLライクな構文を使える拡張機能 です。最終的には通常のJavaScript関数呼び出しに変換されるため、特別なランタイムを必要としません。
JSXの変換プロセス
ステップ | 内容 | ツール |
---|---|---|
1. 記述 | JSXコードを書く | エディタ |
2. トランスパイル | JSXをJavaScriptに変換 | Babel, SWC, esbuild |
3. 実行 | ブラウザで動作 | JavaScript エンジン |
JSXなしのコード例
// JSXを使わない場合
React.createElement('h1', { className: 'question' }, '質問');
JSXありのコード例
// JSXを使った場合
<h1 className="question">質問</h1>
このようにJSXを使うとコードが直感的で可読性が高くなります。
TypeScriptでのJSX
// TypeScriptでは型安全性も確保
type Props = {
title: string;
isActive: boolean;
}
const Header: React.FC<Props> = ({ title, isActive }) => (
<h1 className={isActive ? 'active' : ''}>{title}</h1>
);
2. JSXの利点
2.1 よく知られた構文
JSXはHTMLに似ているため、デザイナーや非エンジニアのメンバーにも理解しやすいです。
2.2 意味的にわかりやすい
カスタムコンポーネントをタグとして使えるため、コードの意図を明確に表現できます。
<Divider>質問</Divider>
2.3 構造が可視化される
複雑なUIもJSXを使うことで見やすく整理できます。
要素 | JSX | 純粋JavaScript |
---|---|---|
ネスト構造 | 視覚的に明確 | 括弧が多く複雑 |
属性 | HTML風で直感的 | オブジェクト形式 |
子要素 | タグ内に配置 | 第3引数以降 |
2.4 抽象化
JSXはトランスパイルによって自動的にJavaScriptへ変換されるため、バージョン差異を意識せず開発できます。
2.5 関心の分離
Reactはテンプレートとロジックを分離するのではなく、コンポーネント単位で管理 します。JSXを使うことで、見た目と処理を直感的に整理できます。
2.6 開発ツールのサポート
最新のIDEやエディタでは、JSXに対する以下のサポートが充実しています:
- 自動補完
- シンタックスハイライト
- エラー検出
- リファクタリング機能
3. コンポーネント合成
3.1 カスタムコンポーネントの定義
function Divider() {
return (
<div className="divider">
<h2>質問</h2>
<hr />
</div>
);
}
3.2 動的な値の利用
const text = '質問';
<h2>{text}</h2>
JavaScriptの式を {}
で囲むことで、動的な値を埋め込めます:
式の種類 | 例 | 結果 |
---|---|---|
変数 | {userName} |
変数の値を表示 |
演算 | {count + 1} |
計算結果を表示 |
関数呼び出し | {getName()} |
返り値を表示 |
三項演算子 | {isLogin ? 'ログイン中' : 'ゲスト'} |
条件分岐 |
3.3 子ノードの扱い
<Divider>質問</Divider>
props.children
を使って、コンポーネントの子要素にアクセスできます。
3.4 Fragment(フラグメント)
複数の要素を返す場合は、Fragment を使用します:
// 長い書き方
<React.Fragment>
<h1>タイトル</h1>
<p>本文</p>
</React.Fragment>
// 短縮記法
<>
<h1>タイトル</h1>
<p>本文</p>
</>
4. JSXとHTMLの違い
4.1 属性名の違い
HTMLとJSXで異なる主な属性名:
HTML | JSX | 理由 |
---|---|---|
class |
className |
JavaScriptの予約語を避けるため |
for |
htmlFor |
JavaScriptの予約語を避けるため |
tabindex |
tabIndex |
キャメルケース統一 |
maxlength |
maxLength |
キャメルケース統一 |
readonly |
readOnly |
キャメルケース統一 |
<label htmlFor="input-id">名前</label>
<input id="input-id" className="form-input" maxLength={50} />
4.2 条件分岐
JSX内ではif文は直接書けませんが、以下の方法で条件分岐を実現できます:
// 三項演算子
<div className={isComplete ? 'done' : 'pending'}></div>
// && 演算子(表示/非表示)
{isVisible && <Modal />}
// 即時関数(複雑な条件)
{(() => {
if (status === 'loading') return <Spinner />;
if (status === 'error') return <Error />;
return <Content />;
})()}
4.3 特別な属性
JSX特有の重要な属性:
属性 | 用途 | 例 |
---|---|---|
key |
リスト要素を一意に識別 | <li key={id}> |
ref |
DOM要素への参照を保持 | <input ref={inputRef}> |
dangerouslySetInnerHTML |
HTML文字列を直接埋め込み(非推奨) | セキュリティリスクあり |
4.4 イベント
イベント名はキャメルケースで記述します:
HTML | JSX |
---|---|
onclick |
onClick |
onchange |
onChange |
onsubmit |
onSubmit |
onfocus |
onFocus |
<button onClick={handleClick}>クリック</button>
<input onChange={(e) => setValue(e.target.value)} />
4.5 スタイル
スタイルはオブジェクトで指定し、プロパティ名はキャメルケースになります:
// インラインスタイル
<div style={{
color: 'red',
fontSize: '20px',
backgroundColor: '#f0f0f0'
}}>
赤い文字
</div>
// Tailwind CSS(推奨)
<div className="text-red-500 text-xl bg-gray-100">
赤い文字
</div>
4.6 自己終了タグ
すべてのタグは必ず閉じる必要があります:
// HTML(閉じタグなし可)
<img src="photo.jpg">
<br>
<input type="text">
// JSX(必ず閉じる)
<img src="photo.jpg" />
<br />
<input type="text" />
5. JSXなしでReactを使う場合
JSXを使わなくてもReactは動作しますが、コードは煩雑になります:
// JSXなし
React.createElement(
'div',
{ className: 'container' },
React.createElement('h2', null, '質問'),
React.createElement('p', null, '回答')
);
// JSXあり(同じ結果)
<div className="container">
<h2>質問</h2>
<p>回答</p>
</div>
JSX vs createElement の比較
観点 | JSX | createElement |
---|---|---|
可読性 | 高い | 低い |
記述量 | 少ない | 多い |
学習コスト | HTML知識で対応可 | React API の理解必要 |
デバッグ | 視覚的に分かりやすい | ネストが深いと困難 |
6. 実践的なベストプラクティス
リストのレンダリング
const items = ['React', 'Vue', 'Angular'];
// keyには安定したユニークな値を使用
<ul>
{items.map((item, index) => (
<li key={item}>{item}</li>
))}
</ul>
フォームの扱い
// 制御コンポーネント
const [value, setValue] = useState('');
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
パフォーマンスの考慮
注意点 | 対策 |
---|---|
不要な再レンダリング | React.memo, useMemo, useCallback を活用 |
key属性の誤用 | インデックスではなく安定したIDを使用 |
インライン関数の多用 | 関数を事前に定義 |
7. モダンな開発環境
推奨される技術スタック
カテゴリ | ツール | 特徴 |
---|---|---|
フレームワーク | Next.js | フルスタック対応、App Router |
スタイリング | Tailwind CSS | ユーティリティファースト |
型チェック | TypeScript | 型安全性の確保 |
フォーマッター | Prettier | コード整形 |
リンター | ESLint | コード品質チェック |
React Server Components
最新のReactでは、サーバーサイドでもJSXを活用できます:
// Server Component(async対応)
async function UserList() {
const users = await fetchUsers();
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
8. まとめ
- JSXはJavaScriptにHTML風の記法を追加するもの
- 可読性が高く、構造をわかりやすく表現できる
- HTMLと似ているが完全に同じではなく、専用のルールがある
- TypeScriptと組み合わせることで型安全性も確保
- モダンなツールチェーンと組み合わせて効率的な開発が可能
- JSXなしでも開発可能だが、基本的には使うのがおすすめ