Reactの条件分岐|三項演算子と&&演算子の使い分け

React開発で迷いがちな条件分岐の書き方を徹底解説。三項演算子と&&演算子の違い、使い分け方法、実際のコード例まで詳しく説明します。

Learning Next 運営
43 分で読めます

みなさん、Reactでコンポーネントを書いていて、条件分岐の書き方に迷ったことはありませんか?

「三項演算子と&&演算子、どっちを使えばいいの?」と思ったことがある方も多いでしょう。 「同じような条件分岐なのに、書き方がバラバラになってしまう...」という経験もあるかもしれません。

実は、React開発において条件分岐は非常に頻繁に使用する機能です。 ログイン状態によってコンポーネントを切り替えたり、データの有無によって表示を変更したりと、さまざまな場面で活用しますよね。

この記事では、Reactの条件分岐における三項演算子と&&演算子の違い使い分け方法を詳しく解説します。 適切な条件分岐の書き方を身につけて、より読みやすく保守性の高いReactコードを書けるようになりましょう。

Reactの条件分岐の基本を理解しよう

まず、Reactにおける条件分岐の基本的な考え方を理解しましょう。 なぜJSXで条件分岐が重要なのかも含めて説明します。

JSXで条件分岐が必要な理由

ReactのJSXでは、HTML的な記法の中でJavaScriptの条件分岐を使用する必要があります。

// 一般的なJavaScriptの条件分岐
function regularJavaScript() {
  if (condition) {
    return 'A';
  } else {
    return 'B';
  }
}

// ReactのJSXでの条件分岐
function ReactComponent({ condition }) {
  return (
    <div>
      {condition ? 'A' : 'B'}
    </div>
  );
}

JSXの中では、if文を直接使用できません。 そのため、式として評価される条件分岐を使用する必要があります。

主な条件分岐の手法

Reactでは以下の条件分岐手法が主に使用されます。

1. 三項演算子(ternary operator)

{condition ? <ComponentA /> : <ComponentB />}

2. 論理AND演算子(&&)

{condition && <ComponentA />}

3. 論理OR演算子(||)

{data || 'デフォルト値'}

4. 関数による条件分岐

{renderConditionalComponent()}

今回は、特によく使用される三項演算子と&&演算子に焦点を当てて解説します。

条件分岐の評価タイミング

Reactの条件分岐は、コンポーネントのレンダリング時に評価されます。

function Example({ user }) {
  console.log('コンポーネントが評価される');
  
  return (
    <div>
      {user ? (
        <div>
          {console.log('ユーザーが存在する場合のみ実行')}
          <p>こんにちは、{user.name}さん</p>
        </div>
      ) : (
        <div>
          {console.log('ユーザーが存在しない場合のみ実行')}
          <p>ログインしてください</p>
        </div>
      )}
    </div>
  );
}

この基本的な仕組みを理解することで、適切な条件分岐手法を選択できるようになります。

三項演算子の使い方をマスターしよう

三項演算子は、条件に応じて異なる値を返したい場合に使用する、最も基本的な条件分岐手法です。

基本的な構文

// 基本形
condition ? trueの場合の値 : falseの場合の値

// 実際の使用例
function UserGreeting({ user }) {
  return (
    <div>
      {user ? `こんにちは、${user.name}さん` : 'ログインしてください'}
    </div>
  );
}

シンプルですが、とても強力な機能です。

コンポーネントの条件分岐

実際のアプリケーションでは、コンポーネント全体を条件分岐で切り替えることがよくあります。

function AuthenticatedApp({ isLoggedIn, user }) {
  return (
    <div>
      <header>
        <h1>マイアプリ</h1>
      </header>
      
      {isLoggedIn ? (
        <main>
          <h2>ダッシュボード</h2>
          <p>ようこそ、{user.name}さん</p>
          <UserDashboard user={user} />
        </main>
      ) : (
        <main>
          <h2>ログイン</h2>
          <p>アカウントにログインしてください</p>
          <LoginForm />
        </main>
      )}
      
      <footer>
        <p>&copy; 2025 My App</p>
      </footer>
    </div>
  );
}

ログイン状態によって、全く異なるコンテンツを表示できます。

スタイルの条件分岐

CSSクラスやスタイルの条件分岐も、三項演算子で簡単に実装できます。

function StatusBadge({ status }) {
  return (
    <span 
      className={`badge ${status === 'active' ? 'badge-success' : 'badge-danger'}`}
      style={{
        backgroundColor: status === 'active' ? '#28a745' : '#dc3545',
        color: 'white'
      }}
    >
      {status === 'active' ? 'アクティブ' : '非アクティブ'}
    </span>
  );
}

クラス名、スタイル、表示テキストを一度に条件分岐できます。

複数条件の三項演算子

複数の条件を組み合わせることも可能です。

function UserStatus({ user }) {
  return (
    <div>
      <h3>ユーザー状態</h3>
      <p>
        {user.role === 'admin' ? (
          '管理者権限'
        ) : user.role === 'editor' ? (
          '編集者権限'
        ) : user.role === 'viewer' ? (
          '閲覧者権限'
        ) : (
          '権限なし'
        )}
      </p>
    </div>
  );
}

ただし、あまり複雑になると読みにくくなるので注意が必要です。

配列やオブジェクトの条件分岐

データの処理でも、三項演算子は活躍します。

function ProductList({ products, category }) {
  const filteredProducts = products.filter(product => 
    category === 'all' ? true : product.category === category
  );
  
  return (
    <div>
      <h2>商品一覧</h2>
      {filteredProducts.length > 0 ? (
        <ul>
          {filteredProducts.map(product => (
            <li key={product.id}>
              {product.name} - {product.price}円
            </li>
          ))}
        </ul>
      ) : (
        <p>該当する商品がありません</p>
      )}
    </div>
  );
}

配列の処理と表示を、一緒に条件分岐できます。

関数の条件分岐

関数の処理結果も、三項演算子で条件分岐できます。

function DataDisplay({ data, isLoading, error }) {
  const formatData = (data) => {
    return data.map(item => ({
      ...item,
      formatted: true
    }));
  };
  
  return (
    <div>
      {error ? (
        <div className="error">
          <p>エラーが発生しました</p>
          <p>{error.message}</p>
        </div>
      ) : isLoading ? (
        <div className="loading">
          <p>読み込み中...</p>
        </div>
      ) : (
        <div className="data">
          {formatData(data).map(item => (
            <div key={item.id}>
              <h4>{item.title}</h4>
              <p>{item.description}</p>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

エラー、ローディング、データ表示を段階的に条件分岐しています。

三項演算子は、必ず何らかの値を返すため、JSXの中で直接使用しやすい特徴があります。

&&演算子の使い方を覚えよう

&&演算子は、条件が真の場合にのみ要素を表示したい場合に使用する条件分岐手法です。

基本的な構文

// 基本形
condition && 表示する要素

// 実際の使用例
function WelcomeMessage({ user }) {
  return (
    <div>
      <h1>ホーム</h1>
      {user && <p>こんにちは、{user.name}さん</p>}
    </div>
  );
}

条件が真の場合のみ、要素が表示されます。 条件が偽の場合は、何も表示されません

条件付きコンポーネント表示

通知やバナーなど、オプショナルな表示に便利です。

function NotificationBanner({ notifications, showBanner }) {
  return (
    <div>
      {showBanner && (
        <div className="notification-banner">
          <h3>お知らせ</h3>
          {notifications.length > 0 && (
            <ul>
              {notifications.map(notification => (
                <li key={notification.id}>
                  {notification.message}
                </li>
              ))}
            </ul>
          )}
        </div>
      )}
    </div>
  );
}

バナーの表示と、通知の有無を段階的に条件分岐しています。

権限ベースの表示制御

ユーザーの権限に応じて、機能を表示・非表示にできます。

function AdminPanel({ user, isAdmin }) {
  return (
    <div>
      <h1>設定</h1>
      
      {/* 基本設定は全員に表示 */}
      <section>
        <h2>基本設定</h2>
        <UserSettings user={user} />
      </section>
      
      {/* 管理者のみに表示 */}
      {isAdmin && (
        <section>
          <h2>管理者設定</h2>
          <AdminSettings />
        </section>
      )}
      
      {/* 特定の権限を持つユーザーのみに表示 */}
      {user.permissions.includes('user_management') && (
        <section>
          <h2>ユーザー管理</h2>
          <UserManagement />
        </section>
      )}
    </div>
  );
}

権限に応じて、必要な機能のみを表示できます。

データ存在確認

データが存在する場合のみ、関連する要素を表示できます。

function UserProfile({ user }) {
  return (
    <div className="user-profile">
      <h1>{user.name}</h1>
      
      {user.avatar && (
        <img 
          src={user.avatar} 
          alt={`${user.name}のアバター`}
          className="avatar"
        />
      )}
      
      {user.bio && (
        <section>
          <h2>自己紹介</h2>
          <p>{user.bio}</p>
        </section>
      )}
      
      {user.skills && user.skills.length > 0 && (
        <section>
          <h2>スキル</h2>
          <ul>
            {user.skills.map(skill => (
              <li key={skill}>{skill}</li>
            ))}
          </ul>
        </section>
      )}
      
      {user.social && (
        <section>
          <h2>SNS</h2>
          {user.social.twitter && (
            <a href={user.social.twitter} target="_blank" rel="noopener noreferrer">
              Twitter
            </a>
          )}
          {user.social.github && (
            <a href={user.social.github} target="_blank" rel="noopener noreferrer">
              GitHub
            </a>
          )}
        </section>
      )}
    </div>
  );
}

オプショナルな情報を、存在する場合のみ表示しています。

フォームの条件付き表示

フォームでは、設定に応じて項目を表示・非表示にできます。

function ContactForm({ showAdvancedOptions, formData, errors }) {
  return (
    <form>
      <div>
        <label>名前</label>
        <input 
          type="text" 
          name="name"
          value={formData.name}
        />
        {errors.name && (
          <span className="error">{errors.name}</span>
        )}
      </div>
      
      <div>
        <label>メールアドレス</label>
        <input 
          type="email" 
          name="email"
          value={formData.email}
        />
        {errors.email && (
          <span className="error">{errors.email}</span>
        )}
      </div>
      
      {showAdvancedOptions && (
        <div className="advanced-options">
          <h3>詳細オプション</h3>
          
          <div>
            <label>
              <input 
                type="checkbox" 
                name="newsletter"
                checked={formData.newsletter}
              />
              ニュースレターを受け取る
            </label>
          </div>
          
          <div>
            <label>優先度</label>
            <select name="priority" value={formData.priority}>
              <option value="low">低</option>
              <option value="medium">中</option>
              <option value="high">高</option>
            </select>
          </div>
        </div>
      )}
      
      <button type="submit">送信</button>
    </form>
  );
}

エラーメッセージや詳細オプションを、必要な場合のみ表示しています。

配列の条件付き処理

配列の処理でも、&&演算子は活躍します。

function ShoppingCart({ items, discountCode }) {
  const subtotal = items.reduce((sum, item) => sum + item.price, 0);
  const discount = discountCode ? subtotal * 0.1 : 0;
  const total = subtotal - discount;
  
  return (
    <div className="shopping-cart">
      <h2>ショッピングカート</h2>
      
      {items.length > 0 ? (
        <div>
          <ul>
            {items.map(item => (
              <li key={item.id}>
                {item.name} - {item.price}円
              </li>
            ))}
          </ul>
          
          <div className="cart-summary">
            <p>小計: {subtotal}円</p>
            
            {discountCode && (
              <p className="discount">
                割引({discountCode}): -{discount}円
              </p>
            )}
            
            <p className="total">合計: {total}円</p>
          </div>
          
          {total > 5000 && (
            <p className="free-shipping">
              送料無料対象です!
            </p>
          )}
          
          <button>購入手続きへ</button>
        </div>
      ) : (
        <p>カートが空です</p>
      )}
    </div>
  );
}

割引の適用や送料無料の表示を、条件に応じて追加しています。

&&演算子は、条件が偽の場合に何も表示しないため、オプショナルな要素の表示に非常に適しています。

使い分けの判断基準を知ろう

三項演算子と&&演算子を適切に使い分けるための、具体的な判断基準を解説します。

基本的な使い分けルール

1. 出力パターンによる使い分け

// A または B を表示したい場合 → 三項演算子
function LoginStatus({ isLoggedIn }) {
  return (
    <div>
      {isLoggedIn ? 'ログイン中' : 'ログインしてください'}
    </div>
  );
}

// A または 何も表示しない場合 → &&演算子
function WelcomeMessage({ user }) {
  return (
    <div>
      <h1>ホーム</h1>
      {user && <p>こんにちは、{user.name}さん</p>}
    </div>
  );
}

必ず何かを表示したい場合は三項演算子を使います。 オプショナルな表示には&&演算子を使います。

2. 条件の複雑さによる使い分け

// 単純な条件 → &&演算子
function SimpleConditional({ showButton, onClick }) {
  return (
    <div>
      {showButton && <button onClick={onClick}>クリック</button>}
    </div>
  );
}

// 複雑な条件 → 三項演算子
function ComplexConditional({ user, loading, error }) {
  return (
    <div>
      {loading ? (
        <div>読み込み中...</div>
      ) : error ? (
        <div>エラー: {error.message}</div>
      ) : user ? (
        <div>こんにちは、{user.name}さん</div>
      ) : (
        <div>ログインしてください</div>
      )}
    </div>
  );
}

単純な条件では&&演算子がすっきり書けます。 複雑な条件では三項演算子が整理しやすくなります。

実際の使用例による比較

ナビゲーションメニュー

function Navigation({ user, isAdmin }) {
  return (
    <nav>
      <ul>
        <li><a href="/">ホーム</a></li>
        
        {/* ログイン状態で表示を切り替え */}
        {user ? (
          <li><a href="/dashboard">ダッシュボード</a></li>
        ) : (
          <li><a href="/login">ログイン</a></li>
        )}
        
        {/* 管理者のみ表示 */}
        {isAdmin && (
          <li><a href="/admin">管理画面</a></li>
        )}
        
        {/* ログイン中のみ表示 */}
        {user && (
          <li><a href="/profile">プロフィール</a></li>
        )}
      </ul>
    </nav>
  );
}

この例では、役割に応じて使い分けをしています。

  • ログイン/ログアウト状態で切り替え:三項演算子
  • 管理者のみ表示:&&演算子
  • ログイン中のみ表示:&&演算子

商品一覧ページ

function ProductList({ products, category, user }) {
  const filteredProducts = products.filter(product => 
    category === 'all' ? true : product.category === category
  );
  
  return (
    <div>
      <h1>商品一覧</h1>
      
      {/* 商品の有無で表示を切り替え */}
      {filteredProducts.length > 0 ? (
        <div className="products-grid">
          {filteredProducts.map(product => (
            <div key={product.id} className="product-card">
              <h3>{product.name}</h3>
              <p>{product.price}円</p>
              
              {/* 在庫状況の表示 */}
              <span className={`stock ${product.stock > 0 ? 'in-stock' : 'out-of-stock'}`}>
                {product.stock > 0 ? '在庫あり' : '在庫切れ'}
              </span>
              
              {/* セール情報の表示 */}
              {product.onSale && (
                <span className="sale-badge">セール中</span>
              )}
              
              {/* ログイン中のみ購入ボタン表示 */}
              {user && product.stock > 0 && (
                <button>カートに追加</button>
              )}
            </div>
          ))}
        </div>
      ) : (
        <p>該当する商品がありません</p>
      )}
    </div>
  );
}

この例でも、用途に応じて使い分けをしています。

  • 商品の有無で表示切り替え:三項演算子
  • 在庫状況の表示:三項演算子
  • セール情報の表示:&&演算子
  • 購入ボタンの表示:&&演算子

判断基準のチェックリスト

三項演算子を使う場合

  • 条件によって異なる2つの値を表示したい
  • 必ず何らかの値を返したい
  • 複数の条件を組み合わせたい
  • if-else文の代替として使いたい

&&演算子を使う場合

  • 条件が真の場合のみ表示したい
  • 条件が偽の場合は何も表示しない
  • オプショナルな要素を表示したい
  • 単純な条件での表示制御

コードの可読性を考慮した使い分け

複雑な条件分岐は、関数に分けることで読みやすくなります。

// 読みにくい例:過度に複雑な三項演算子
function BadExample({ user, loading, error, data }) {
  return (
    <div>
      {loading ? (
        <div>Loading...</div>
      ) : error ? (
        <div>Error: {error.message}</div>
      ) : user ? (
        user.role === 'admin' ? (
          <AdminDashboard data={data} />
        ) : user.role === 'editor' ? (
          <EditorDashboard data={data} />
        ) : (
          <UserDashboard data={data} />
        )
      ) : (
        <LoginForm />
      )}
    </div>
  );
}

// 読みやすい例:関数による条件分岐
function GoodExample({ user, loading, error, data }) {
  const renderContent = () => {
    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;
    if (!user) return <LoginForm />;
    
    switch (user.role) {
      case 'admin':
        return <AdminDashboard data={data} />;
      case 'editor':
        return <EditorDashboard data={data} />;
      default:
        return <UserDashboard data={data} />;
    }
  };
  
  return (
    <div>
      {renderContent()}
    </div>
  );
}

複雑な条件分岐は関数に分離することで、可読性が大幅に向上します。

パフォーマンスを考慮した使い分け

function PerformanceExample({ items, showExpensiveComponent }) {
  return (
    <div>
      <h1>商品一覧</h1>
      
      {/* 単純な条件は&&演算子で軽量 */}
      {items.length > 0 && (
        <p>{items.length}件の商品があります</p>
      )}
      
      {/* 重い処理は条件付きで実行 */}
      {showExpensiveComponent && (
        <ExpensiveDataVisualization data={items} />
      )}
      
      {/* 条件によって異なるコンポーネント */}
      {items.length > 10 ? (
        <VirtualizedList items={items} />
      ) : (
        <SimpleList items={items} />
      )}
    </div>
  );
}

重い処理は条件付きで実行することで、パフォーマンスを向上させられます。

適切な使い分けにより、コードの可読性と保守性を大幅に向上させることができます。

実践的なコード例で学ぼう

実際のアプリケーション開発でよく遭遇するシーンでの条件分岐を、具体的なコード例で解説します。

ダッシュボードアプリケーション

function Dashboard({ user, notifications, tasks, weather }) {
  const [showNotifications, setShowNotifications] = useState(false);
  const [selectedTab, setSelectedTab] = useState('overview');
  
  return (
    <div className="dashboard">
      <header className="dashboard-header">
        <h1>ダッシュボード</h1>
        
        {/* ユーザー情報の表示 */}
        <div className="user-info">
          {user.avatar ? (
            <img src={user.avatar} alt="アバター" className="avatar" />
          ) : (
            <div className="avatar-placeholder">
              {user.name.charAt(0)}
            </div>
          )}
          <span>{user.name}</span>
        </div>
        
        {/* 通知ベル */}
        <div className="notifications">
          <button 
            onClick={() => setShowNotifications(!showNotifications)}
            className={notifications.length > 0 ? 'has-notifications' : ''}
          >
            🔔
            {notifications.length > 0 && (
              <span className="notification-count">
                {notifications.length}
              </span>
            )}
          </button>
          
          {showNotifications && (
            <div className="notification-dropdown">
              {notifications.length > 0 ? (
                <ul>
                  {notifications.map(notification => (
                    <li key={notification.id}>
                      <strong>{notification.title}</strong>
                      <p>{notification.message}</p>
                      <small>{notification.createdAt}</small>
                    </li>
                  ))}
                </ul>
              ) : (
                <p>新しい通知はありません</p>
              )}
            </div>
          )}
        </div>
      </header>
      
      <main className="dashboard-content">
        {/* タブナビゲーション */}
        <nav className="tab-nav">
          <button 
            className={selectedTab === 'overview' ? 'active' : ''}
            onClick={() => setSelectedTab('overview')}
          >
            概要
          </button>
          <button 
            className={selectedTab === 'tasks' ? 'active' : ''}
            onClick={() => setSelectedTab('tasks')}
          >
            タスク ({tasks.length})
          </button>
          {user.role === 'admin' && (
            <button 
              className={selectedTab === 'admin' ? 'active' : ''}
              onClick={() => setSelectedTab('admin')}
            >
              管理
            </button>
          )}
        </nav>
        
        {/* タブコンテンツ */}
        <div className="tab-content">
          {selectedTab === 'overview' && (
            <OverviewTab user={user} weather={weather} />
          )}
          
          {selectedTab === 'tasks' && (
            <TasksTab tasks={tasks} />
          )}
          
          {selectedTab === 'admin' && user.role === 'admin' && (
            <AdminTab />
          )}
        </div>
      </main>
    </div>
  );
}

このダッシュボードでは、様々な条件分岐を使い分けています。

  • アバターの表示:三項演算子(画像かプレースホルダー)
  • 通知数の表示:&&演算子(通知がある場合のみ)
  • 管理者タブ:&&演算子(管理者のみ)
  • タブコンテンツ:&&演算子(選択されたタブのみ)

概要タブのコンポーネント

function OverviewTab({ user, weather }) {
  const currentTime = new Date().getHours();
  
  const getGreeting = () => {
    if (currentTime < 12) return 'おはようございます';
    if (currentTime < 18) return 'こんにちは';
    return 'こんばんは';
  };
  
  return (
    <div className="overview-tab">
      <h2>{getGreeting()}、{user.name}さん</h2>
      
      {/* 天気情報 */}
      {weather && (
        <div className="weather-widget">
          <h3>今日の天気</h3>
          <div className="weather-info">
            <span className="temperature">{weather.temperature}°C</span>
            <span className="condition">{weather.condition}</span>
            {weather.humidity > 70 && (
              <span className="humidity-alert">
                湿度が高めです ({weather.humidity}%)
              </span>
            )}
          </div>
        </div>
      )}
      
      {/* 今日の予定 */}
      <div className="today-schedule">
        <h3>今日の予定</h3>
        {user.todayTasks && user.todayTasks.length > 0 ? (
          <ul>
            {user.todayTasks.map(task => (
              <li key={task.id}>
                <span className={task.completed ? 'completed' : ''}>
                  {task.title}
                </span>
                {task.urgent && (
                  <span className="urgent-badge">緊急</span>
                )}
              </li>
            ))}
          </ul>
        ) : (
          <p>今日の予定はありません</p>
        )}
      </div>
    </div>
  );
}

このコンポーネントでは、データの存在確認が主な条件分岐です。

  • 天気情報の表示:&&演算子(データがある場合のみ)
  • 湿度アラート:&&演算子(条件を満たす場合のみ)
  • 今日の予定:三項演算子(データの有無で切り替え)
  • 緊急バッジ:&&演算子(緊急タスクのみ)

ECサイトの商品詳細ページ

function ProductDetail({ product, user, reviews }) {
  const [selectedImage, setSelectedImage] = useState(0);
  const [quantity, setQuantity] = useState(1);
  
  const averageRating = reviews.length > 0 
    ? reviews.reduce((sum, review) => sum + review.rating, 0) / reviews.length
    : 0;
    
  const canPurchase = product.stock > 0 && user;
  const isOnSale = product.salePrice && product.salePrice < product.regularPrice;
  const savings = isOnSale ? product.regularPrice - product.salePrice : 0;
  
  return (
    <div className="product-detail">
      <div className="product-images">
        <div className="main-image">
          <img 
            src={product.images[selectedImage]} 
            alt={product.name}
          />
          {isOnSale && (
            <div className="sale-badge">
              {Math.round((savings / product.regularPrice) * 100)}% OFF
            </div>
          )}
        </div>
        
        {product.images.length > 1 && (
          <div className="thumbnail-images">
            {product.images.map((image, index) => (
              <img
                key={index}
                src={image}
                alt={`${product.name} ${index + 1}`}
                className={selectedImage === index ? 'active' : ''}
                onClick={() => setSelectedImage(index)}
              />
            ))}
          </div>
        )}
      </div>
      
      <div className="product-info">
        <h1>{product.name}</h1>
        
        {/* 価格情報 */}
        <div className="price-info">
          {isOnSale ? (
            <div>
              <span className="sale-price">¥{product.salePrice.toLocaleString()}</span>
              <span className="regular-price">¥{product.regularPrice.toLocaleString()}</span>
              <span className="savings">¥{savings.toLocaleString()}お得</span>
            </div>
          ) : (
            <span className="price">¥{product.regularPrice.toLocaleString()}</span>
          )}
        </div>
        
        {/* 評価 */}
        {reviews.length > 0 && (
          <div className="rating-info">
            <span className="stars">
              {'★'.repeat(Math.floor(averageRating))}
              {'☆'.repeat(5 - Math.floor(averageRating))}
            </span>
            <span className="rating-text">
              {averageRating.toFixed(1)} ({reviews.length}件のレビュー)
            </span>
          </div>
        )}
        
        {/* 在庫状況 */}
        <div className="stock-info">
          {product.stock > 0 ? (
            <span className="in-stock">
              在庫あり
              {product.stock <= 5 && (
                <span className="low-stock"> (残り{product.stock}個)</span>
              )}
            </span>
          ) : (
            <span className="out-of-stock">在庫切れ</span>
          )}
        </div>
        
        {/* 購入フォーム */}
        {canPurchase && (
          <div className="purchase-form">
            <div className="quantity-selector">
              <label>数量:</label>
              <select 
                value={quantity} 
                onChange={(e) => setQuantity(parseInt(e.target.value))}
              >
                {[...Array(Math.min(product.stock, 10))].map((_, i) => (
                  <option key={i + 1} value={i + 1}>
                    {i + 1}
                  </option>
                ))}
              </select>
            </div>
            
            <button className="add-to-cart-btn">
              カートに追加
            </button>
            
            {user.isPremium && (
              <button className="buy-now-btn">
                今すぐ購入
              </button>
            )}
          </div>
        )}
        
        {/* ログインが必要な場合 */}
        {!user && (
          <div className="login-required">
            <p>購入にはログインが必要です</p>
            <button className="login-btn">ログイン</button>
          </div>
        )}
        
        {/* 配送情報 */}
        {product.freeShipping && (
          <div className="shipping-info">
            <span className="free-shipping">送料無料</span>
          </div>
        )}
        
        {user && user.address && (
          <div className="delivery-info">
            <p>お届け先: {user.address}</p>
            <p>
              お届け予定: 
              {product.fastDelivery ? '明日' : '2-3日以内'}
            </p>
          </div>
        )}
      </div>
    </div>
  );
}

このECサイトの例では、商品の状態やユーザーの状態に応じて、適切な条件分岐を使い分けています。

  • セールバッジ:&&演算子(セール中のみ)
  • サムネイル画像:&&演算子(複数画像がある場合のみ)
  • 価格表示:三項演算子(セール価格か通常価格)
  • 評価表示:&&演算子(レビューがある場合のみ)
  • 在庫状況:三項演算子(在庫ありか在庫切れ)
  • 購入フォーム:&&演算子(購入可能な場合のみ)
  • プレミアム機能:&&演算子(プレミアムユーザーのみ)

これらの実践的な例では、三項演算子と&&演算子を適切に使い分けて、複雑な条件分岐を効率的に実装しています。

まとめ:条件分岐をマスターしよう

この記事では、Reactの条件分岐における三項演算子と&&演算子の使い分けについて詳しく解説しました。

重要なポイント

1. 基本的な使い分け

  • 三項演算子: A または B を表示したい場合
  • &&演算子: A または 何も表示しない場合

2. 判断基準

  • 三項演算子: 条件によって異なる値を返したい
  • &&演算子: 条件付きで要素を表示したい

3. 実践的な活用

  • ユーザー状態による表示切り替え
  • 権限ベースの表示制御
  • データの有無による条件分岐
  • フォームの条件付き表示

使い分けのまとめ

場面推奨手法理由
ログイン/ログアウト表示三項演算子必ずどちらかを表示
オプション機能の表示&&演算子条件時のみ表示
エラー/成功メッセージ三項演算子状態に応じた表示
権限ベースの機能&&演算子権限がある場合のみ
データ有無の判定&&演算子データがある場合のみ

コードの品質向上のために

1. 可読性を重視

  • 複雑な条件分岐は関数に分割
  • 適切なコメントの追加

2. 一貫性を保つ

  • プロジェクト内で統一したルール
  • チームでの規約策定

3. パフォーマンスを考慮

  • 不要な再レンダリングを回避
  • 条件の評価コストを意識

今後の学習

条件分岐を理解したら、次は以下のトピックにも取り組んでみてください。

  • React.memo: 不要な再レンダリングの防止
  • useMemo: 計算結果のキャッシュ
  • useCallback: 関数の最適化
  • Suspense: 非同期データの条件分岐

適切な条件分岐の書き方をマスターすることで、より効率的で保守性の高いReactアプリケーションを開発できるようになります。

ぜひ、この知識を活かして、美しいReactコードを書いてみてください!

関連記事