
JSX!
JSXとは?なぜReactで使うのか
JSX(JavaScript XML)は、Reactアプリケーション開発において欠かせない技術の一つです。簡単に言うと、JavaScript の中でHTMLのようなマークアップを直接書ける拡張構文のことです。
従来のWeb開発では、HTML、CSS、JavaScriptを別々のファイルで管理していました。しかし、モダンなWebアプリケーションでは、ユーザーインターフェース(UI)の表示内容がJavaScriptのロジックに大きく依存するようになりました。
JSXを使用することで、以下のメリットが得られます:
- 視認性の向上:UIの構造とロジックを一箇所で確認できる
- 開発効率の向上:HTMLとJavaScriptを行き来する必要がない
- 型安全性:コンパイル時にエラーを検出しやすい
- 保守性:関連するコードがまとまっているため変更が容易
豆知識: JSXはFacebookの開発者が2013年にReactと共に発表しました。当初は「HTMLとJavaScriptを混ぜるのは良くない」という批判もありましたが、現在では多くの開発者に受け入れられています。
JSXの基本的な書き方
最もシンプルなJSXの例
まずは、最も基本的なJSXの書き方を見てみましょう:
function WelcomeMessage() {
  return <h1>こんにちは、React初心者の皆さん!</h1>;
}
export default WelcomeMessage;この例では、WelcomeMessageという関数コンポーネントがJSXを返しています。一見するとHTMLそのものですが、実際はJavaScriptコードの一部です。
JSXの重要なルール
JSXを書く際には、HTMLとは異なる重要なルールがいくつかあります。
ルール1: 必ず単一の親要素で囲む
❌ 間違った書き方
function UserProfile() {
  return (
    <h2>田中太郎</h2>
    <p>Web開発者</p>
  );
}✅ 正しい書き方
function UserProfile() {
  return (
    <div>
      <h2>田中太郎</h2>
      <p>Web開発者</p>
    </div>
  );
}または、余分なDOMノードを作りたくない場合は、React.Fragment(省略記法:<></>)を使用します。
function UserProfile() {
  return (
    <>
      <h2>田中太郎</h2>
      <p>Web開発者</p>
    </>
  );
}ルール2: すべてのタグは必ず閉じる
❌ HTML形式(JSXでは使えない)
<img src="profile.jpg" alt="プロフィール画像">
<input type="text" name="username">✅ JSX形式
<img src="profile.jpg" alt="プロフィール画像" />
<input type="text" name="username" />ルール3: 属性名はキャメルケースで記述
❌ HTML形式
<div class="profile-card">
  <button onclick="handleClick()">クリック</button>
</div>✅ JSX形式
<div className="profile-card">
  <button onClick={handleClick}>クリック</button>
</div>注意: classはclassNameに、forはhtmlForに変更する必要があります。これらはJavaScriptの予約語と衝突するためです。
HTMLからJSXへ変換
実際のHTMLをJSXに変換する過程を、ショッピングカードのコンポーネントを例に見てみましょう。
変換前のHTML
<div class="product-card">
  <img src="https://example.com/laptop.jpg" alt="ノートパソコン">
  <h3>高性能ノートパソコン</h3>
  <p class="price">¥89,800</p>
  <button class="add-to-cart" onclick="addToCart()">カートに追加</button>
</div>変換後のJSX
function ProductCard() {
  const handleAddToCart = () => {
    console.log('カートに追加されました');
  };
  return (
    <div className="product-card">
      <img 
        src="https://example.com/laptop.jpg" 
        alt="ノートパソコン" 
      />
      <h3>高性能ノートパソコン</h3>
      <p className="price">¥89,800</p>
      <button 
        className="add-to-cart" 
        onClick={handleAddToCart}
      >
        カートに追加
      </button>
    </div>
  );
}
export default ProductCard;変更点の解説
- class→- classNameに変更
- <img>タグに- />を追加して自己完結タグに
- onclick→- onClickに変更し、文字列ではなく関数を直接指定
- 全体をReact関数コンポーネントとしてラップ
JSXでのJavaScript活用法(波括弧の使い方)
JSXの真価は、波括弧 {} を使ってJavaScriptの式を埋め込めることにあります。これにより、動的なコンテンツを簡単に表示できます。
変数の表示
function UserGreeting() {
  const userName = '佐藤花子';
  const currentTime = new Date().toLocaleTimeString('ja-JP');
  
  return (
    <div>
      <h2>{userName}さん、こんにちは!</h2>
      <p>現在時刻: {currentTime}</p>
    </div>
  );
}計算式の実行
function ShoppingCart() {
  const itemPrice = 1200;
  const quantity = 3;
  const taxRate = 0.1;
  
  return (
    <div className="cart-summary">
      <p>商品価格: ¥{itemPrice}</p>
      <p>数量: {quantity}個</p>
      <p>小計: ¥{itemPrice * quantity}</p>
      <p>税込合計: ¥{Math.floor((itemPrice * quantity) * (1 + taxRate))}</p>
    </div>
  );
}条件分岐による表示制御
function ProductStatus() {
  const stockCount = 5;
  const isOnSale = true;
  
  return (
    <div className="product-info">
      <h3>商品在庫状況</h3>
      {stockCount > 0 ? (
        <p className="in-stock">在庫あり({stockCount}点)</p>
      ) : (
        <p className="out-of-stock">在庫切れ</p>
      )}
      
      {isOnSale && <span className="sale-badge">セール中!</span>}
    </div>
  );
}配列データの表示(リストレンダリング)
function RecommendedProducts() {
  const products = [
    { id: 1, name: 'ワイヤレスマウス', price: 2980 },
    { id: 2, name: 'キーボード', price: 8900 },
    { id: 3, name: 'モニター', price: 24800 }
  ];
  
  return (
    <div className="recommended-products">
      <h3>おすすめ商品</h3>
      <ul>
        {products.map(product => (
          <li key={product.id}>
            {product.name} - ¥{product.price.toLocaleString()}
          </li>
        ))}
      </ul>
    </div>
  );
}重要: 配列をレンダリングする際は、必ず各要素に一意のkey属性を設定してください。これによりReactが効率的に画面更新を行えます。
オブジェクトスタイルの適用
function StyledCard() {
  const cardStyle = {
    backgroundColor: '#f8f9fa',
    border: '1px solid #dee2e6',
    borderRadius: '8px',
    padding: '20px',
    boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
  };
  
  const titleStyle = {
    color: '#495057',
    fontSize: '24px',
    marginBottom: '16px'
  };
  
  return (
    <div style={cardStyle}>
      <h2 style={titleStyle}>スタイル付きカード</h2>
      <p>JSXでインラインスタイルを適用した例です。</p>
    </div>
  );
}注意: CSS のプロパティ名はキャメルケースで記述します(例:background-color → backgroundColor)。また、値は文字列またはオブジェクトとして指定します。
よくある間違いと解決法
「Objects are not valid as a React child」エラー
❌ エラーの原因
function UserInfo() {
  const user = { name: '田中太郎', age: 30 };
  
  return (
    <div>
      <p>ユーザー情報: {user}</p>
    </div>
  );
}✅ 正しい書き方
function UserInfo() {
  const user = { name: '田中太郎', age: 30 };
  
  return (
    <div>
      <p>名前: {user.name}</p>
      <p>年齢: {user.age}歳</p>
    </div>
  );
}未定義値による表示エラー
❌ エラーが発生する可能性
function ProductPrice({ product }) {
  return (
    <p>価格: ¥{product.price}</p>
  );
}✅ 安全な書き方
function ProductPrice({ product }) {
  return (
    <p>
      価格: ¥{product?.price || '価格未定'}
    </p>
  );
}JSXでのコメントの書き方
function CommentExample() {
  return (
    <div>
      {/* これはJSXコメントです */}
      <h2>商品詳細</h2>
      
      {/* 
        複数行のコメントも
        このように書けます
      */}
      <p>商品の説明文</p>
    </div>
  );
}実践的な例:ショッピングカートコンポーネント
これまで学んだ内容を統合して、実用的なショッピングカートコンポーネントを作成してみましょう:
function ShoppingCartApp() {
  const cartItems = [
    {
      id: 1,
      name: 'プログラミング入門書',
      price: 3200,
      quantity: 1,
      image: 'https://example.com/book1.jpg'
    },
    {
      id: 2,
      name: 'ワイヤレスキーボード',
      price: 12800,
      quantity: 2,
      image: 'https://example.com/keyboard.jpg'
    }
  ];
  const calculateTotal = (items) => {
    return items.reduce((total, item) => total + (item.price * item.quantity), 0);
  };
  const formatPrice = (price) => {
    return price.toLocaleString();
  };
  const total = calculateTotal(cartItems);
  const tax = Math.floor(total * 0.1);
  const finalTotal = total + tax;
  return (
    <div className="shopping-cart">
      <header>
        <h1>🛒 ショッピングカート</h1>
        <p>{cartItems.length}点の商品があります</p>
      </header>
      <main>
        {cartItems.length === 0 ? (
          <p className="empty-cart">カートに商品がありません</p>
        ) : (
          <div className="cart-items">
            {cartItems.map(item => (
              <div key={item.id} className="cart-item">
                <img 
                  src={item.image} 
                  alt={item.name}
                  className="item-image"
                />
                <div className="item-details">
                  <h3>{item.name}</h3>
                  <p className="item-price">
                    ¥{formatPrice(item.price)} × {item.quantity}個
                  </p>
                  <p className="item-subtotal">
                    小計: ¥{formatPrice(item.price * item.quantity)}
                  </p>
                </div>
              </div>
            ))}
          </div>
        )}
      </main>
      {cartItems.length > 0 && (
        <footer className="cart-summary">
          <div className="summary-row">
            <span>商品合計:</span>
            <span>¥{formatPrice(total)}</span>
          </div>
          <div className="summary-row">
            <span>消費税:</span>
            <span>¥{formatPrice(tax)}</span>
          </div>
          <div className="summary-row total">
            <strong>
              <span>合計:</span>
              <span>¥{formatPrice(finalTotal)}</span>
            </strong>
          </div>
          <button className="checkout-button">
            レジに進む
          </button>
        </footer>
      )}
    </div>
  );
}
export default ShoppingCartApp;この例では以下のJSXテクニックを活用しています:
- 変数の埋め込み:商品名や価格の表示
- 関数の呼び出し:価格フォーマット、合計計算
- 条件分岐:空カートの場合の表示切り替え
- 配列レンダリング:商品一覧の表示
- 論理演算子:条件に応じたフッター表示
まとめと次のステップ
JSXマスターのポイント
この記事で学んだJSXの重要なポイントを振り返ってみましょう:
- 基本ルールの理解:単一親要素、タグの閉じ、キャメルケース
- 波括弧の活用:JavaScript式の埋め込み、動的コンテンツの表示
- 条件分岐とリスト:ユーザーインターフェースの動的制御
- エラー対策:よくある間違いとその回避方法
- 実践的な応用:複数のテクニックを組み合わせた実装
学習を続けるための次のステップ
JSXの基礎を理解したら、以下の内容に進むことをお勧めします:
- コンポーネント設計:再利用可能なコンポーネントの作成方法
- Props(プロパティ):コンポーネント間でのデータ受け渡し
- State(状態管理):動的なデータの管理とユーザーインタラクション
- イベントハンドリング:ユーザーアクションへの応答
- ライフサイクル:コンポーネントの生成・更新・破棄のタイミング
実践のすすめ: JSXは読むだけでなく、実際に手を動かして書くことで理解が深まります。CodeSandboxやCodePenなどのオンラインエディターで、今日学んだ例を改造してみることから始めてみてください。
おわりに
JSXは最初は HTML と JavaScript が混在することに戸惑うかもしれませんが、慣れてしまえば非常に直感的で効率的な記述方法です。この記事で紹介した基本をしっかりと身につけて、次のステップへと進んでみてください。
React の世界は奥が深く、JSX はその入り口に過ぎません。継続的な学習と実践を通じて、魅力的なWebアプリケーションを構築できるようになっていきましょう。








