React JSX完全入門!初心者でもわかるJSXの基本と活用法

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>

注意: classclassNameに、forhtmlForに変更する必要があります。これらは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の重要なポイントを振り返ってみましょう:

  1. 基本ルールの理解:単一親要素、タグの閉じ、キャメルケース
  2. 波括弧の活用:JavaScript式の埋め込み、動的コンテンツの表示
  3. 条件分岐とリスト:ユーザーインターフェースの動的制御
  4. エラー対策:よくある間違いとその回避方法
  5. 実践的な応用:複数のテクニックを組み合わせた実装

学習を続けるための次のステップ

JSXの基礎を理解したら、以下の内容に進むことをお勧めします:

  • コンポーネント設計:再利用可能なコンポーネントの作成方法
  • Props(プロパティ):コンポーネント間でのデータ受け渡し
  • State(状態管理):動的なデータの管理とユーザーインタラクション
  • イベントハンドリング:ユーザーアクションへの応答
  • ライフサイクル:コンポーネントの生成・更新・破棄のタイミング

実践のすすめ: JSXは読むだけでなく、実際に手を動かして書くことで理解が深まります。CodeSandboxやCodePenなどのオンラインエディターで、今日学んだ例を改造してみることから始めてみてください。

おわりに

JSXは最初は HTML と JavaScript が混在することに戸惑うかもしれませんが、慣れてしまえば非常に直感的で効率的な記述方法です。この記事で紹介した基本をしっかりと身につけて、次のステップへと進んでみてください。

React の世界は奥が深く、JSX はその入り口に過ぎません。継続的な学習と実践を通じて、魅力的なWebアプリケーションを構築できるようになっていきましょう。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次