İçeriğe geç
react

React'te Koşullu Render: Pattern'ler ve En İyi Uygulamalar

Tarık Tunç
React'te Koşullu Render: Pattern'ler ve En İyi Uygulamalar

React'te Koşullu Render: Pattern'ler ve En İyi Uygulamalar

Koşullu render (conditional rendering), bileşenlerin farklı durumlar için farklı içerikler göstermesini sağlar. Kullanıcının oturum durumu, veri yükleme aşaması, hata halleri veya kullanıcı tercihlerine göre UI'ı dinamik olarak değiştirmek React uygulamalarının temelini oluşturur. Bu yazıda React'te koşullu render'ın tüm yöntemlerini, her birinin artı ve eksilerini ve gerçek dünya kullanım örneklerini inceleyeceğiz.

1. if/else ile Koşullu Render

En basit ve okunabilir yöntem, erken return ile if/else kullanmaktır:

function Dashboard({ user, isLoading, error }) {
  // Erken return pattern'i - önce edge case'leri ele al
  if (isLoading) {
    return (
      <div className="loading-state">
        <div className="spinner" />
        <p>Veriler yükleniyor...</p>
      </div>
    );
  }

  if (error) {
    return (
      <div className="error-state">
        <h3>Bir hata oluştu</h3>
        <p>{error.message}</p>
        <button onClick={() => window.location.reload()}>Tekrar Dene</button>
      </div>
    );
  }

  if (!user) {
    return (
      <div className="empty-state">
        <p>Kullanıcı bulunamadı.</p>
      </div>
    );
  }

  // Ana içerik
  return (
    <div className="dashboard">
      <h2>Hoş geldin, {user.name}!</h2>
      <p>Son giriş: {user.lastLogin}</p>
    </div>
  );
}

2. Ternary Operatör

JSX içinde koşullu render'ın en yaygın yöntemidir. İki durumlu (if/else) senaryolar için idealdir:

function AuthButton({ isLoggedIn, onLogin, onLogout }) {
  return (
    <div>
      {isLoggedIn ? (
        <div>
          <span>Hoş geldiniz!</span>
          <button onClick={onLogout}>Çıkış Yap</button>
        </div>
      ) : (
        <div>
          <span>Lütfen giriş yapın</span>
          <button onClick={onLogin}>Giriş Yap</button>
        </div>
      )}
    </div>
  );
}

Uyarı: İç içe ternary operatörler kodun okunabilirliğini ciddi şekilde azaltır. Birden fazla koşul söz konusu olduğunda erken return pattern'i veya ayrı bir fonksiyon kullanın.

3. Mantıksal AND (&&) Operatörü

Bir koşul doğru olduğunda bir şey göstermek, yanlış olduğunda hiçbir şey göstermemek için kullanılır:

function Notifications({ notifications, unreadCount }) {
  return (
    <div className="notifications">
      <h3>Bildirimler</h3>

      {/* unreadCount > 0 kontrolü - 0 render edilmesini engeller */}
      {unreadCount > 0 && (
        <span className="badge">{unreadCount} okunmamış</span>
      )}

      {/* Array kontrolü */}
      {notifications.length > 0 && (
        <ul>
          {notifications.map(n => (
            <li key={n.id} className={n.read ? '' : 'unread'}>{n.message}</li>
          ))}
        </ul>
      )}

      {/* Boş durum */}
      {notifications.length === 0 && (
        <p className="empty">Bildirim bulunmuyor.</p>
      )}
    </div>
  );
}

Bilgi: {count && <span>{count}</span>} ifadesinde count 0 ise ekranda "0" yazısı görünür. Bunun nedeni JavaScript'te 0 && 'anything' ifadesinin 0 döndürmesidir ve React 0'ı render eder. Her zaman boolean sonuç üreten karşılaştırmalar kullanın: {count > 0 && ...}

4. Switch/Case ile Çoklu Koşullar

function OrderStatus({ status }) {
  const renderStatus = () => {
    switch (status) {
      case 'pending':
        return <span className="status pending">Beklemede</span>;
      case 'processing':
        return <span className="status processing">İşleniyor</span>;
      case 'shipped':
        return <span className="status shipped">Kargoda</span>;
      case 'delivered':
        return <span className="status delivered">Teslim Edildi</span>;
      case 'cancelled':
        return <span className="status cancelled">İptal Edildi</span>;
      default:
        return <span className="status unknown">Bilinmiyor</span>;
    }
  };

  return <div className="order-status">{renderStatus()}</div>;
}

5. Object Lookup Pattern

Switch/case yerine daha deklaratif bir yaklaşım:

function AlertIcon({ type }) {
  const icons = {
    info: <svg>{/* info icon */}</svg>,
    success: <svg>{/* success icon */}</svg>,
    warning: <svg>{/* warning icon */}</svg>,
    error: <svg>{/* error icon */}</svg>
  };

  return icons[type] || icons.info;
}

// Component mapping pattern
const STEP_COMPONENTS = {
  personal: PersonalInfoStep,
  address: AddressStep,
  payment: PaymentStep,
  review: ReviewStep
};

function MultiStepForm({ currentStep }) {
  const StepComponent = STEP_COMPONENTS[currentStep];

  if (!StepComponent) {
    return <p>Geçersiz adım</p>;
  }

  return <StepComponent />;
}

6. IIFE (Immediately Invoked Function Expression)

function ComplexCondition({ user }) {
  return (
    <div>
      {(() => {
        if (user.role === 'admin' && user.isVerified) {
          return <AdminDashboard />;
        }
        if (user.role === 'editor') {
          return <EditorPanel />;
        }
        if (user.subscription === 'premium') {
          return <PremiumContent />;
        }
        return <BasicContent />;
      })()}
    </div>
  );
}

İpucu: IIFE pattern'i JSX içinde karmaşık koşullar için kullanışlı olsa da, kodun okunabilirliğini azaltabilir. Karmaşık koşulları ayrı bir fonksiyona veya bileşene çıkarmak daha temiz bir yaklaşımdır.

Koşullu Class ve Style Uygulaması

function Button({ variant, size, disabled, children }) {
  // Template literal ile koşullu className
  const className = [
    'btn',
    `btn-${variant}`,
    `btn-${size}`,
    disabled && 'btn-disabled'
  ].filter(Boolean).join(' ');

  return (
    <button className={className} disabled={disabled}>
      {children}
    </button>
  );
}

// clsx veya classnames kütüphanesi ile
// import clsx from 'clsx';
// const className = clsx('btn', `btn-${variant}`, { 'btn-disabled': disabled });

Null Render ve Fragment

// null döndürerek hiçbir şey render etmeme
function ConditionalTooltip({ show, text, children }) {
  if (!show) return null;

  return (
    <div className="tooltip-wrapper">
      {children}
      <span className="tooltip">{text}</span>
    </div>
  );
}

Sonuç

React'te koşullu render için tek bir "en iyi" yöntem yoktur. Durum karmaşıklığına göre doğru aracı seçmek önemlidir: basit iki durumlu koşullar için ternary, tek koşullu gösterim için AND operatörü, çoklu durumlar için switch/case veya object lookup, ve karmaşık mantık için erken return pattern'i. Kodunuzun okunabilirliğini her zaman ön planda tutun.

Kaynaklar

İlgili Yazılar