Hadisələrin Emal Edilməsi

React elementlərində hadisələrin emal edilməsi DOM elementlərindəkinə bənzəyir. Amma bəzi sintaktik fərqlər var:

  • React hadisələrinə lowercase yox camelCase istifadə edilərək ad verilir.
  • JSX ilə string yerinə funksiya hadisə işlədicisi kimi ötürülür.

Misal üçün aşağıdakı HTML:

<button onclick="activateLasers()">
  Lazerləri aktivləşdir
</button>

React-dəkindən bir az fərqlidir:

<button onClick={activateLasers}>
  Lazerləri aktivləşdir
</button>

Başqa bir fərq ondan ibarətdir ki, React-də false qaytarmaqla default davranışın qarşısını almaq olmur. Bunu etmək üçün preventDefault açıq şəkildə çağırılmalıdır. Məsələn, sadə HTML ilə linkin ilkin davranışını (yeni səhifə açmaq) ləğv etmək üçün belə yaza bilərsiniz:

<a href="#" onclick="console.log('Linkə tıklandı.'); return false">
  Mənə tıkla
</a>

React-də bunu belə yazmaq olar:

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('Linkə tıklandı.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Mənə tıkla
    </a>
  );
}

Burada e sintetik hadisədir. React sintetik hadisələri W3C spesifikasiyasına uyğun olaraq təyin edir. Bu isə o deməkdir ki, brauzerlər arası uyğunluqdan narahat olmamaq olar. Daha ətraflı məlumat üçün SyntheticEvent referans təlimatına nəzər yetirin.

React istifadə edərkən DOM elementi yarandıqdan sonra işləyici əlavə etmək üçün addEventListener çağırmağa ehtiyac yoxdur. Əvəzinə işləyicini element ilk dəfə render olunduqda ötürmək olar.

Komponent ES6 klası kimi təyin olunduqda hadisə işləyicisi klasın metodlarından biri ola bilər. Məsələn, aşağıdakı Toggle komponenti istifadəçiyə “ON” və “OFF” halları arasında dəyişməyə imkan verən düyməyə render olunur:

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

    // Bu binding `this`-in callback-də işləməsi üçün önəmlidir
    this.handleClick = this.handleClick.bind(this);
  }

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

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

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

CodePen-də bax

JSX callback-lərində this ilə işləyərkən ehtiyatlı olmaq lazımdır. JavaScript-də klas metodları ilkin olaraq kontekstə bağlanmayıb (bind). Əgər this.handleClick-i bağlamasaq və onu onClick-ə ötürməyi unutsaq, funksiya çağırıldıqda this undefined olacaq.

Bu spesifik olaraq React-ə aid davranış deyil, JavaScript-də funksiyalar ümumiyyətlə belə işləyir. Metodu sonunda mötərizəsiz istifadə etməklə də bağlamaq olar. Məsələn: onClick={this.handleClick}.

Əgər bind xoşunuza gəlmirsə, iki alternativ yolunuz var. Birincisi sınaq vəziyyətində olan public klas sahələri sintaksisi istifadə etməkdir. Bu sahələri callback-ləri düzgün bağlamaq üçün istifadə etmək olar:

class LoggingButton extends React.Component {
  // Bu sintaksis `this`-in handleClick-ə bind olunduğuna zəmanət verir.
  // Diqqət: bu *experimental* sintaksisdir.
  handleClick = () => {
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Mənə tıkla
      </button>
    );
  }
}

Bu sintaksis Create React App-da ilkin olaraq qoşulub.

Əgər sahə sintaksisi istifadə etmirsinizsə, onda callback-də arrow funksiyaları istifadə edə bilərsiniz:

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // Bu sintaksis `this`-in handleClick-ə bind olunduğuna zəmanət verir
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Mənə tıkla
      </button>
    );
  }
}

Bu sintaksisin çatışmazlığı ondan ibarətdir ki, hər dəfə LoggingButton render olanda yeni callback yaradılır. Əksər hallarda bu problem deyil. Lakin əgər bu callback prop kimi uşaq komponentlərə ötürülürsə, onda həmin komponentlər əlavə render işi görə bilər. Belə performans problemlərini aradan qaldırmaq üçün konstruktorda bağlamaq və ya klas sahələri sintaksisindən istifadə etmək məsləhət görülür.

Arqumentlərin hadisə işləyicilərinə ötürülməsi

Loop-un daxilində hadisə işləyicisinə əlavə parametr ötürmək lazım ola bilər. Məsələn, əgər id sıra ID-sidirsə aşağıdakı variantlardan birini istifadə etmək olar:

<button onClick={(e) => this.deleteRow(id, e)}>Sıranı sil</button>
<button onClick={this.deleteRow.bind(this, id)}>Sıranı sil</button>

Bu iki sətir eyni işi görür, və müvafiq olaraq arrow funksiyalarıFunction.prototype.bind istifadə edir.

Hər iki halda, React hadisəsini təmsil edən e arqumenti, ID-dən sonra ikinci parametr kimi ötürüləcək. Arrow funksiyaları istifadə etdikdə bu arqument açıq şəkildə ötürülür, lakin bind ilə bu avtomatik baş verir.