React bileşenlerinizde çoğu zaman farklı koşullar altında farklı şeyler render etmek isteyeceksiniz. React’te, if ifadesi, &&, ve ? : gibi JavaScript sözdizimine (syntax) ait operatörleri kullanarak koşullu olarak JSX render edebilirsiniz.

Bunları öğreneceksiniz

  • Bir koşula bağlı olarak farklı JSX nasıl döndürülür
  • Koşullu olarak bir JSX parçası nasıl dahil edilir veya hariç tutulur
  • React kod tabanında karşınıza çıkacak yaygın kullanılan kısayol koşul sözdizimleri

Koşullu olarak JSX döndürmek

Diyelim ki elinizde bir PackingList bileşeni var. Bu bilesen, bavula konulup konulmadıklarına göre işaretlenebilen, Item’ bileşeninden birkaç tane render ediyor:

function Item({ name, isPacked }) {
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

Bazı Item bileşenlerinin isPacked prop’unun false (yanlış) yerine true (doğru) olduğuna dikkat edin. Eğer bileşen prop’u isPacked={true} ise eşyaların yanında bir tik (✔) işareti olmalı.

Bunu bir if/else ifadesi olarak şöyle yazabilirsiniz:

if (isPacked) {
return <li className="item">{name}</li>;
}
return <li className="item">{name}</li>;

Eğer isPacked prop’u true ise, bu kod farklı bir JSX ağacı döndürür. Bu değişiklikle birlikte, bazı eşya isimlerinin yanına tik işareti gelir:

function Item({ name, isPacked }) {
  if (isPacked) {
    return <li className="item">{name}</li>;
  }
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

Her iki durumda da döndürülenleri düzenlemeyi deneyin ve sonucun nasıl değiştiğini görün!

JavaScript’in if ve return ifadeleriyle nasıl branching (dallanma) mantığı yarattığınıza dikkat edin. React’te kontrol akışı (koşullar gibi) JavaScript tarafından gerçekleştirilir.

null ile koşullu olarak hiçbir şey döndürmemek

Bazı durumlarda hiçbir şey render etmemek isteyebilirsiniz. Örneğin, bavula konmuş eşyaların listenizde görünmesini istemiyorsunuz ancak bir bileşen bir şey döndürmek zorundadır. Bu durumda null döndürebilirsiniz:

if (isPacked) {
return null;
}
return <li className="item">{name}</li>;

Eğer isPacked prop’u true (doğru) ise, bileşen hiçbir şey yani null döndürecektir. Aksi takdirde, render etmek için JSX’i döndürecektir.

function Item({ name, isPacked }) {
  if (isPacked) {
    return null;
  }
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

Uygulamada, bir bileşenin null döndürmesi yaygın olarak kullanılan bir şey değildir çünkü bileşeni render etmek isteyen başka bir geliştiriciyi şaşırtabilir. Daha sık olarak, bir bileşeni üst bileşeninin JSX’ine koşullu olarak dahil eder veya hariç tutarsınız. Şimdi bunu nasıl yapacağımızı öğrenelim!

JSX’i koşullu olarak dahil etmek

Önceki örnekte bileşen tarafından (eğer varsa!) hangi JSX ağacının döndüreleceğini belirlediniz. Render edilen çıktıda bazı tekrarlamalar olduğunu farketmişsinizdir:

<li className="item">{name}</li>

bu iki ifade birbirine çok benzemekte

<li className="item">{name}</li>

Her iki koşul da <li className="item">...</li> ifadesini döndürmekte:

if (isPacked) {
return <li className="item">{name}</li>;
}
return <li className="item">{name}</li>;

Bu tekrarlamalar zararlı olmasa bile yazdığınız kodu idame ettirmek zorlaşacaktır. Ya className’i değiştirmek isterseniz? Bu işlemi kodunuzda iki yerde yapmak zorundasınız! Bu gibi durumlarda, kodunuz daha DRY. (Tekrar Etme Kendini - TEK) hale getirmek için koşullu olarak küçük bir JSX ekleyebilirsiniz.

Koşullu (ternary) operatörü (? :)

JavaScript, koşullu bir ifade yazmak için kompakt bir sözdizimine sahiptir — koşullu operatör ya da “ternary operatörü”.

Böyle yazmak yerine:

if (isPacked) {
return <li className="item">{name}</li>;
}
return <li className="item">{name}</li>;

Şöyle yazabilirsiniz:

return (
<li className="item">
{isPacked ? name + ' ✔' : name}
</li>
);

Bu kodu şöyle okuyabilirsiniz: “eğer isPacked prop’u true (doğru) ise, o zaman (?) name + ' ✔' render et, aksi halde (:) name render et”.

Derinlemesine İnceleme

Bu iki örnek tamamen eşdeğer mi?

Nesne yönelimli programlama geçmişiniz varsa, yukarıdaki iki örneğin biraz farklı olduğunu çünkü birinin iki farklı <li> kopyası oluşturabileceğini düşünebilirsiniz. Ancak JSX öğeleri herhangi bir dahili state’e sahip olmadıkları ve gerçek DOM node’u olmadıkları için bir “kopya” değildir. JSX öğeleri aynı blueprint’ler (kılavuz) gibi tanımlardır. Yani bu iki örnek birbiriyle tamamen aynıdır. State’i korumak ve sıfırlamak bunun nasıl çalıştığını ayrıntılı bir şekilde anlatmaktadır.

Şimdi, bavula konmuş eşyanının isminin üstünü listenizde çizmek için <del> HTML elementini kullanmak istiyorsunuz. Her durumda da daha fazla JSX’i iç içe yerleştirmeyi kolaylaştırmak için daha fazla yeni satır ve parantez ekleyebilirsiniz:

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {isPacked ? (
        <del>
          {name + ' ✔'}
        </del>
      ) : (
        name
      )}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

Kodunuzu bu şekilde yazmak basit koşullu ifadeler için güzel çalışmakta ancak dikkatli kullanmakta fayda vardır. Eğer bileşenleriniz iç içe geçmiş çok fazla koşullu ifadeden oluşuyorsa, ifadeyi temizlemek için yeni bir alt bileşen oluşturabilirsiniz. React’te, biçimlendirme kodunuzun bir parçasıdır dolayısıyla karmaşık ifadeleri düzenlemek için değişkenler ve fonksiyonlar gibi araçları kullanabilirsiniz.

Mantıksal AND (VE) operatörü (&&)

Karşınıza sıkça çıkacak bir diğer kısayol ise JavaScript mantıksal AND (VE) (&&) operatörüdür. Bu operatör React bileşeni içinde genellikle koşul doğru olduğunda bir kısım JSX’i render etmek aksi halde hiçbir şey render etmemek istediğiniz durumlarda kullanılır. && ifadesi ile, yalnızca isPacked prop’u true (doğru) ise tik işaretini eşyanın isminin yanına koyabilirsiniz.

return (
<li className="item">
{name} {isPacked && '✔'}
</li>
);

Bu kodu şu şekilde okuyabilirsiniz: “eğer isPacked prop’u true (doğru) ise, o zaman (&&) tik işaretini render et, yoksa render etme”.

Aşağıda nasıl çalıştığını görebilirsiniz:

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✔'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

JavaScript && operatörü eğer ifademizin sol tarafı (koşulumuz) true (doğru)ise ifadenin sağ tarafındaki değeri döndürür. Ama koşulumuz false (yanlış) ise, bütün ifademiz false (yanlış) olur. React, false’u JSX ağacında tıpkı null ya da undefined gibi bir “delik” olarak kabul eder ve geriye hiçbir şey döndürmez.

Tuzak

&& operatörünün sol tarafına numara koymayın.

JavaScript koşulu test etmek için operatörün sol tarafını otomatik olarak boole (true-false) dönüştürür. Bununla birlikte, eğer sol taraf 0 rakamı ise, ifadenin tamamı 0 değerini alır ve React, hiçbir şey döndürmemek yerine mutlu bir şekilde 0 render edecektir.

Örneğin, messageCount && <p>New messages</p> gibi bir kod yazmak yaygın bir hatadır. messageCount 0 olduğunda hiçbir şey render etmediğini varsaymak kolaydır ancak React gerçekte 0 render etmektedir.

Bu durumu düzeltmek için sol tarafı boolean’a (boole) çevirmek gereklidir: messageCount > 0 && <p>New messages</p>.

Bir değişkene koşullu olarak JSX atamak

Kısayollar düz kod yazmanın önüne geçtiği zaman, bir if ifadesi ve bir değişken kullanmayı deneyebilirsiniz. let ile tanımlanmış değişkenlere başka değerler atayabilirsiniz, bu nedenle ilk olarak görüntülemek istediğimiz varsayılan değer olan name’i atayalım:

let itemContent = name;

Eğer isPacked true (doğru) ise, bir JSX ifadesini itemContent’e tekrardan atamak için bir if ifadesi kullanın:

if (isPacked) {
itemContent = name + " ✔";
}

Süslü parantezler “JavaScript’e bir pencere” açar. Önceden hesaplanmış olan değişkeni süslü parantez içinde şu şekilde JSX içinde kullanabilirsiniz:

<li className="item">
{itemContent}
</li>

Bu yöntem en ayrıntılı ama aynı zamanda en esnek olanıdır. Aşağıda nasıl çalıştığını görebilirsiniz:

function Item({ name, isPacked }) {
  let itemContent = name;
  if (isPacked) {
    itemContent = name + " ✔";
  }
  return (
    <li className="item">
      {itemContent}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

Daha önce olduğu gibi bu yalnızca metin için değil, koşullu JSX için de çalışır:

function Item({ name, isPacked }) {
  let itemContent = name;
  if (isPacked) {
    itemContent = (
      <del>
        {name + " ✔"}
      </del>
    );
  }
  return (
    <li className="item">
      {itemContent}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

Eğer JavaScript diline aşina değilseniz, bu yöntem çeşitliliği ilk başta kafa karıştırıcı olabilir. Ancak bunları öğrenmek, sadece React bileşenleri değil, herhangi bir JavaScript kodunu okumanıza ve yazmanıza yardımcı olacaktır! Başlangıçta tercih ettiğiniz sözdizimi ile devam ederek, diğer sözdizimlerin nasıl çalıştığını unuttuğunuz zaman bu sayfayı referans olarak kullanabilirsiniz.

Özet

  • React’te, branching (dallanma) mantığını JavaScript ile kontrol edersiniz.
  • if ifadesini kullanarak koşullu olarak bir JSX ifadesi döndürebilirsiniz.
  • Bir JSX ifadesini koşullu olarak bir değişkene atayabilir ve süslü parantez kullanarak ("") başka bir JSX’in içine dahil edebilirsiniz.
  • JSX’te, {cond ? <A /> : <B />} ifadesi şu anlama gelmektedir: “eğer cond varsa, <A />’yı render et, aksi halde <B />’yi render et”.
  • JSX’te, {cond && <A />} ifadesi şu anlama gelmektedir: “eğer cond varsa, <A />’yı render et, aksi halde hiçbir şey render etme”.
  • Kod tabanlarında bu kısayolları görmek yaygındır, ancak kendiniz düz if ifadesini tercih edebilirsiniz.

Problem 1 / 3:
Bavula konmamış eşyalar için ? : sözdizimini kullanarak bir ikon göster

Koşul operatörünü (cond ? a : b) kullanarak eğer isPacked prop’u true (doğru) değilse ❌ render et.

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✔'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}