Click ve Change Olayları

React elementleri ile click ve change gibi olayları izlemek, DOM elementlerindeki olayları işlemekle çok benzerdir.

Click, change gibi olaylara event denir. Tam liste için tıklayınız. Daha akılda kalıcı olması ve ağırlıklı olarak click ve change olayları kullanıldığı için başlıktada event olayları yerine click ve change olayları başlığını kullandım.

Bazı syntax farklılıkları vardır:

camelCase’den daha öncede bahsetmiştik. İlk kelime hariç diğer kelimelerin ilk harfleri büyük ve birleşik yazılır. Arada - (tire) kullanılmaz. React’te class yerine className, tabindex yerine tabIndex, onclick yerine onClick, onchange yerine onChange kullanılır.)

Örneğin, HTML’de:

<button onclick="activateLasers()">
  Linki aktifleştir
</button>

React’te ise biraz farklıdır:

<button onClick={activateLasers}>
  Linki aktifleştir
</button>

Başka bir fark ise React’te varsayılan davranışı engellemek için false return etmektir. preventDefault‘u açıkça çağırmalısınız. Örneğin, düz HTML’de yeni bir sayfayı açmanın varsayılan bağlantı davranışını önlemek için şunları yazabilirsiniz:

<a href="#" onclick="console.log('Bağlantıya tıklandı.'); return false">
  Tıkla
</a>

React’te bunun yerine:

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('Bağlantıya tıklandı.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Tıkla
    </a>
  );
}

Burada, e sentetik bir olaydır. React, bu sentetik olayları W3C spesifikasyonuna göre tanımlar; dolayısıyla tarayıcılar arası uyumluluk konusunda endişelenmenize gerek yoktur.

React’i kullanırken genellikle bir DOM elementi oluşturulduktan sonra, o elementin click eventini izlemek için addEventListeneri çağırmamamız gerekir. Bunun yerine, element başlangıçta oluşturulduğunda bir click izleyicisi oluşturun.

Bir componenti ES6 classı kullanarak tanımladığınızda, ortak bir desen, bir olay işleyicisinin classtaki bir fonksiyon olmasını sağlar. Örneğin, bu Toggle componenti, kullanıcının “Açık” ve “Kapalı” durumları arasında geçiş yapmasını sağlayan bir buton oluşturur:

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // Click, change gibi olayların çalışabilmesi için aşağıdaki gibi bind etmek gerekir.
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'Açık' : 'Kapalı'}
      </button>
    );
  }
}

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

CodePen’de Deneyin

Bind etmek ile ilgili detaylı bilgi için Turhan Coşkun’un yazdığı JavaScript ile Call, Apply ve Bind Kullanımı adlı makaleyi okuyabilirsiniz.

JSX geriçağırımlarında bu konuda dikkatli olmalısınız. JavaScript’te, class fonskyionları varsayılan olarak bağlı değildir. this.handleClick‘i bind etmeyi (bağlamayı) unutursanız ve onClicke iletirseniz, fonksiyon çağrıldığında bu undefined olur.

Bu, React’e özgü davranış değildir; fonksiyonların JavaScript’te nasıl işlediğinin bir parçasıdır. Genellikle, onClick = {this.handleClick} gibi bir yöntemin arkasından () olmadan işaret ederseniz, bu yöntemi bind etmeniz gerekir.

Bu şekilde bind etmek istemiyorsanız, iki farklı yolu daha vardır.

class LoggingButton extends React.Component {
  // Bu syntax `this`'nin clickOlayi içinde bağlanmasını sağlar.
  // Uyarı: Bu *deneysel* bir syntaxtır.
  handleClick = () => {
    console.log(this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Tıkla
      </button>
    );
  }
}

Bu syntax Create React App‘te varsayılan olarak etkindir.

Return işleminde bir ok fonksiyonu kullanabilirsiniz:

class LoggingButton extends React.Component {
  handleClick() {
    console.log(this);
  }

  render() {
    // Bu syntax `this`'in bind edilmesini sağlar.
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Tıkla
      </button>
    );
  }
}

Bu syntax ile ilgili sorun, LoggingButtonun her işleyişinde farklı bir callback oluşturulmasıdır. Çoğu durumda, bu iyidir. Bununla birlikte bu callback, alt componentlere props olarak iletilirse, bu componentler ek bir yeniden oluşturma işleyebilir. Genellikle, constructorde bind etmenizi öneririz.

Bağımsız Değişkenleri Event Olaylarına Aktarma

Bir döngü içinde, bir event olayına fazladan bir parametre göndermek isteyebilirsiniz. Örneğin, id satır kimliğiyse, aşağıdakilerden herhangi biri işe yarayabilir:

<button onClick={(e) => this.deleteRow(id, e)}>Satırı Sil</button>
<button onClick={this.deleteRow.bind(this, id)}>Satırı Sil</button>

Yukarıdaki iki satır eşittir, ok fonksiyonlarını ve Function.prototype.bindı kullanır.

Her iki durumda da, React olayını temsil eden e argümanı id’den sonra ikinci bir parametre olarak aktarılır. Bir ok fonskiyonu ile bunu açıkça belirtmeliyiz, ancak bind ile başka argümanlar otomatik olarak iletilir.

Sıradaki Eğitim: Şartlı Render