Koşullu Renderlama

React’te, ihtiyacınız olan duruma göre farklı bileşenler oluşturabilirsiniz. Böylelikle, uygulamanızın durumuna göre, yalnızca bileşenlerinizin bazılarını renderlayabilirsiniz.

React’te, koşullu renderlama aynı Javascript’te olduğu gibi çalışır. Javascript’teki if veya koşul operatörü, size uygulamanızın durumuna göre bileşen renderlama imkanı sunar. Ve React, arayüzde uygun bileşeni render eder.

Bu iki bileşeni dikkate alalım:

function UserGreeting(props) {
  return <h1>Hoş geldiniz!</h1>;
}

function GuestGreeting(props) {
  return <h1>Lütfen kayıt olun</h1>;
}

Greeting adında bir bileşen daha oluşturuyoruz. Bu bileşen, kullanıcının giriş yapma durumuna göre yukarıda yazdığımız bileşenleri gösterecek.

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

ReactDOM.render(
  // Kodu değiştirerek deneyin: isLoggedIn={true}:
  <Greeting isLoggedIn={false} />,
  document.getElementById('root')
);

Codepen’de Deneyin

Bu örnek uygulama, isLoggedIn değerine göre farklı bir karşılama yapacak.

Eleman Değişkenleri

HTML elemanlarını saklamak için değişkenleri kullanabilirsiniz. Bu size, bileşen yaratırken, bileşenin bir bölümünü koşullu hale getirmenize yardım eder.

Aşağıdaki iki yeni bileşenin Giriş ve Çıkış butonlarını temsil ettiğini varsayalım:

function LoginButton(props) {
  return (
    <button onClick={props.onClick}>
      Giriş Yap
    </button>
  );
}

function LogoutButton(props) {
  return (
    <button onClick={props.onClick}>
      Çıkış Yap
    </button>
  );
}

Bu örnek bloğunda, LoginControlü stateful component yardımıyla oluşturacağız.

LoginControl, o anki durumuna göre <LoginButton /> ya da <LogoutButton /> bileşenlerininden birini render edecek. Ayrıca, önceki örnekteki <Greeting /> bileşenini de render edecek.

class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    let button;

    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
}

ReactDOM.render(
  <LoginControl />,
  document.getElementById('root')
);

CodePen’de Deneyin

Bir değişken tanımlamak ve if ifadesini kullanmak, bir bileşeni koşullu olarak render etmek için iyi bir yol olsa da, bazen daha kısa bir sözdizimi kullanmak isteyebilirsiniz. JSX’te satir içi koşullama yapmanın, aşağıda açıklanan, birkaç yolu vardır.

Mantıksal && Operatörü ile Tek Satırda if

Süslü parantez kullanarak istediğiniz ifadeyi JSX içine gömebilirsiniz. Buna Javascript’teki mantıksal && operatörü de dahildir. Bu bileşenin içinde koşul vermek için kullanışlı olabilir:

function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Merhaba!</h1>
      {unreadMessages.length > 0 &&
        <h2>
          {unreadMessages.length} adet okunmamış mesajınız var.
        </h2>
      }
    </div>
  );
}

const messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
  <Mailbox unreadMessages={messages} />,
  document.getElementById('root')
);

CodePen’de Deneyin

Bu Javascript üzerinde çalışır çünkü true && expression her zaman expression kısmını çalıştırır fakat false && expression her zaman false döndürür.

Bu yüzden, eğer koşulunuz true ise, &&‘den sonra yazacaklarınız çıktı olur. Eğer koşulunuz false ise, React onu görmezden gelip, geçececektir.

Koşul Operatörü ile Tek Satırda if-else

Koşullu renderlama için farklı bir yöntem ise Javascript koşul operatörünü condition ? true : false kullanmaktır.

Bu örnekte, yazının yalnızca bir kısmını koşullayacağız

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      Bu kullanıcı şuan <b>{isLoggedIn ? 'çevrimiçi' : 'çevrimdışı'}</b>.
    </div>
  );
}

Neler olduğu daha az belirgin olsa da, daha büyük ifadeler için de kullanılabilir:

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleLogoutClick} />
      ) : (
        <LoginButton onClick={this.handleLoginClick} />
      )}
    </div>
  );
}

Javascript’te olduğu gibi, hangisinin daha iyi bir yaklaşım olduğu, size ve sizin takımınıza kalmıştır. Bu arada, ne zaman koşullandırma çok karmaşık bir hal almaya başlarsa extract a component yapmanın zamanı gelmiştir.

Bileşenin Renderlanmasını Engellemek

Nadir durumlarda, renderlanmış bir bileşenin kendisini gizlemesini isteyebilirsiniz. Böyle durumlarda null return edin.

Bu örnekle, WarningBanner bileşeni kendisinin warn özelliğine göre kendini render edecektir. Eğer bu özellik false olursa, bileşen render edilmeyecek.

function WarningBanner(props) {
  if (!props.warn) {
    return null;
  }

  return (
    <div className="warning">
      Bu konuda seni uyarıyorum!
    </div>
  );
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showWarning: true};
    this.handleToggleClick = this.handleToggleClick.bind(this);
  }

  handleToggleClick() {
    this.setState(state => ({
      showWarning: !state.showWarning
    }));
  }

  render() {
    return (
      <div>
        <WarningBanner warn={this.state.showWarning} />
        <button onClick={this.handleToggleClick}>
          {this.state.showWarning ? 'Gizle' : 'Göster'}
        </button>
      </div>
    );
  }
}

ReactDOM.render(
  <Page />,
  document.getElementById('root')
);

CodePen’de Deneyin

Bir bileşenin, render metodundan null döndürmesi yaşam döngüsü metodlarının çalışmasını engellemez. Örneğin componentDidUpdate gerektiği zaman çalışmaya devam edecek.