Обработка событий


Самое базовое событие клик. Добавляется нужному элементу при помощи свойства onClick в которое передаётся функция.

export default class TodoListItem extends Component {
  render() {
  const { label, important = false } = this.props;
    return (
        <span
          className="todo-list-item-label"
          onClick = {() => console.log(`${label}`)}>
          {label}
        </span>
    );
  };
}

Если функция содержит больше одной строки кода, помещать её в JSX нерационально.
Попробуем вынести функцию из JSX  внутрь класса.
Вот такой код вызывает ошибку TypeError: Cannot read property 'props' of undefined:

export default class TodoListItem extends Component {
  onLabelClick () {
    console.log(`${this.props.label}`);
  }
  
  render() {
  const { label, important = false } = this.props;

  return ( 
      <span
        className="todo-list-item-label"
        onClick = {this.onLabelClick}>
        {label}
      </span>
    );
  };
}

Причина в том, что функция onLabelClick не наследует this и ничего не знает о нём. Когда она была стрелочной, сохраняла значение и ошибки не было, но сейчас нам нужно как-то передать ей значение this .
Способов для этого есть три.
Первый - плохой. Приводится только для того, чтобы знать, что так делать не нужно. Для передачи контекста мы можем использовать метод .bind()

onClick = {this.onLabelClick.bind(this)}

Такой код работает, но при каждом вызове функции render будет вызываться новая функция, которая будет оборачивать onLabelClick. Именно так работает метод .bind(). При активной работе приложения такая особенность может привести к проблемам с производительностью.

Второй способ - традиционный.
Мы добавляем конструктор класса и записываем функцию onLabelClick внутри его, преобразуя её в стрелочную

  constructor() {
    super();
    this.onLabelClick = () => {
      console.log(`${this.props.label}`);
    };
  }

Третий способ - использование полей класса. Он ещё не добавлен в стандарт, но благодаря Babel мы можем использовать и такие возможности тоже. Мы просто добавляем стрелочную функцию внутрь класса. Такой способ действительно наиболее простой для понимания и использования.

export default class TodoListItem extends Component {
  onLabelClick = () => {
      console.log(`${this.props.label}`);
    };
  
  render() {
  const { label, important = false } = this.props;

  return (    
      <span
        className="todo-list-item-label"
        onClick = {this.onLabelClick}>
        {label}
      </span>
    );
  };


То есть, чтобы передать событие элементу, мы в его коде пишем

onClick = {this.onLabelClick}

А в коде класса пишем стрелочную функцию (это важно). которая должна выполняться по клику.

Стрелочная функция, это всегда примерно так
  onLabelClick = () => {
      // здесь код 
    };

Разумеется, имя функции может быть произвольным.