Эвентүүдийг удирдах

React элементүүд дээр эвент удирдах нь DOM элементүүдийхтэй тун адилхан. Эдгээрт бага зэрэг синтаксийн ялгаа л бий:

  • React эвентүүд бүгдийг жижгээр бичихийн оронд үгийн эхний үсэг болгоныг(camelCase) стандартаар бичигддэг.
  • JSX-р тэмдэгтийн оронд эвент удирдах функц дамжуулж болдог.

Жишээлбэл, дараах HTML:

<button onclick="activateLasers()">
  Activate Lasers
</button>

React дээр бага зэрэг өөр:

<button onClick={activateLasers}>
  Activate Lasers
</button>

Өөр нэг ялгаа бол React дээр үндсэн ажиллагааг нь зогсоохын тулд худал буцааж болдоггүй. Та preventDefault-г тусгайлан дуудах хэрэгтэй. Жишээлбэл, энгийн HTML дээр линк дээр дарахад шинэ хуудас дууддаг ажиллагаа болиулахдаа дараах байдлаар бичдэг бол:

<a href="#" onclick="console.log('The link was clicked.'); return false">
  Click me
</a>

React дээр дараах байдалтай бичигдэнэ:

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}

Энд e нь синтетик эвент юм. React эдгээр синтетик эвэнтүүдийг W3C тодорхойлолт-н дагуу тодорхойлдог учир та хөтөч хооронд зохицон ажиллах тал дээр санаа зовохгүй байж болно. Илүү дэлгэрэнгүй SyntheticEvent-н талаар илүү мэдмээр байвал баримтжуулалтыг нь үзнэ үү.

React ашиглаж байхад DOM элемент руу addEventListener сонсогчийг дуудах шаардлагагүй байдаг. Үүний оронд сонсогчоо элементийг анх дүрслэхэд олгох хэрэгтэй.

ES6 класс ашиглан компонент тодорхойлж байгаа бол эвент удирдагч нь класс дотор байгаа функц байдаг нь нийтлэг хэвшил юм. Жишээлбэл, энэ Toggle компонент товч дүрслээд хэрэглэгчийг “ON” ба “OFF” төлөвт шилжих боломжийг олгож байна:

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

    // This binding is necessary to make `this` work in the callback
    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 дээр турших

JSX дуудалт дээр this-г ашиглахдаа болгоомжтой байх хэрэгтэй. Жаваскрипт дээр классийн функцууд нь холбогдоогүй(bind) байдаг. Хэрэв та this.handleClick-г холбоод onClick-д дамжуулахаа мартвал this нь функц дуудагдах үед тодорхойлогдоогүй байх болно.

Энэ нь React-д зориулсан ажиллах зарчим биш; функцууд Жаваскрипт дээр хэрхэн ажилладаг талаарх нэг хэсэг юм. Ерөнхийдөө та функцийг ардаа ()-гүй заахад, жишээлбэл onClick={this.handleClick}, та энэ функцийг холбох юм.

Холбох дуудалт танд хэцүү санагдаж байвал өөрөөр хийх хоёр арга бий. Хэрэв та туршилтын public class fields syntax ашиглаж байгаа бол, холбох дуудалтыг классын талбар ашиглаж хийж болно:

class LoggingButton extends React.Component {
  // Энэ синтакс нь `this`-г handleClick-тэй холбох болно.
  // Анхаар: Энэ бол *туршилтын* бичиглэл юм.
  handleClick = () => {
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}

Энэ бичиглэл Create React App дээр анхнаасаа идэвхжүүлэгдсэн байдаг.

Хэрэв та классын талбар бичиглэлийг ашиглахгүй бол та суман функц дуудалт дотор ашиглаж болно:

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

  render() {
    // Энэ синтакс нь `this`-г handleClick-тэй холбох болно.
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
    );
  }
}

Энэ бичиглэлийн асуудал нь LogginButton-г дүрслэх болгонд өөр өөр дуудалт үүсгэх юм. Ихэнх тохиолдолд энэ нь зүгээр байдаг ч энэ дуудалт нь доод түвшний компонент руу шинж чанар болон дамжуулагдахад эдгээр компонентууд нь нэмэлт дахин дүрслэлт(re-rendering) хийж болзошгүй. Энэ мэтчилэн хурдны асуудлаас сэргийлэхийн тулд бид ихэвчлэн холболтыг байгуулагч дотор эсвэл классын талбар бичиглэл ашиглах хийхийг зөвлөдөг.

Эвент удирдагч руу аргумент дамжуулах нь

Давталт дотор эвент удирдагч руу нэмэлт аргумент дамжуулахийг хүсэх нь элбэг. Жишээлбэл, хэрэв id нь мөрийн ID бол дараах хоёр хоёулаа ажиллана:

<button onClick={(e) => this.deleteRow(id, e)}>Мөр устгах</button>
<button onClick={this.deleteRow.bind(this, id)}>Мөр устгах</button>

Дээрх хоёр мөрүүд нь ижилхэн бөгөөд суман функц болон Function.prototype.bind ашигласан байна.

Аль ч тохиолдолд e аргумент нь React-н эвентийг төлөөлөх бөгөөд ID-н дараа хоёрдох аргумент болон дамжуулагдана. Суман функцэд бид тусгайлан зааж өгөх бол bind-д автоматаар дамжих болно.