@glebvvs

Почему события React работают только через стрелочные функции?

Не могу понять вероятно простую вещь. Почему когда я свойству changeStylesForCaption присваиваю стрелочную функцию, то событие onClick заголовка H1 срабатывает.

Но если вместо стрелочной функции использую анонимную или же свойство changeStylesForCaption делаю методом класса, то вылетает такая ошибка:
Cannot read property 'setState' of undefined


В чем магия этих стрелочных функций? Или это какая-то мне непонятная особенность JSX?

import React, { Component } from 'react';

class MainPage extends Component {

  changeStylesForCaption = () => {
    this.setState({
      color: 'black'
    });
  }

  constructor(props) {
    super(props);
    this.state = {
      color: 'red'
    };
  }  

	render() {
		return (
			<h1 onClick={this.changeStylesForCaption} style={{ color: this.state.color }}>gleb</h1>
		);
	}

}

export default MainPage;
  • Вопрос задан
  • 2424 просмотра
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
Потому-что когда вы вызываете метод на объекте:
obj.method(); // вызываем метод
или:
this.method(); // вызываем метод
Ссылка на объект указанная перед точкой будет использована в качестве контекста и будет доступна в функции, через ключевое слово this.

Когда вы передаете метод без вызова:
onClick={obj.method} // не вызываем метод
или:
onClick={this.method} // не вызываем метод
Передается лишь метод, а контекст теряется.

Чтобы не терялся контекст при передаче метода в слушатель, можно использовать функцию bind. На вашем примере:
class MainPage extends Component {
  constructor(props) {
    super(props);
    this.state = {
      color: 'red'
    };
    this.changeStylesForCaption = this.changeStylesForCaption.bind(this); // привязываем контекст
  }  
  
  changeStylesForCaption() {
    this.setState({
      color: 'black'
    });
  }

  render() {
    return (
      <h1 onClick={this.changeStylesForCaption} style={{ color: this.state.color }}>gleb</h1>
    );
  }

}


Стрелочные функции контекста не имеют и используют контекст того окружения, где они определены.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы