// Суть проблемы
// Есть функция handleRun
class ContactsPage extends Component {
constructor(props) {
super(props);
this.state.name = 'Вася';
}
getName() {
alert(this.state.name); // Ожидаем увидеть Васю
}
}
// Такой запуск с кнопки не будет работать
<button onClick={this.getName}>Запустить!</button>
// Причина в потере контекста https://learn.javascript.ru/bind
// Поэтому для начала нужно "забиндить" функцию (передать ей нужный контекст, тот самый объект, где свойство name вполне себе существует)
<button onClick={this.getName.bind(this)}>Запустить!</button>
// Но можно использовать эту возможность более удобно:
// например, разработчики реакт предлагают заюзать конструктор
constructor(props) {
super(props);
this.getName = this.getName.bind(this);
}
<button onClick={this.getName}>Запустить!</button>
// Упростим выржение, если будем использовать стрелочную функцию. Т.к. Стрелочные функции ES6 сохраняют контекст выполнения при вызове.
constructor(props) {
super(props);
this.getName = () => this.getName();
}
<button onClick={this.getName}>Запустить!</button>
// А теперь используем возможности инициализатора свойств ES7. Можно также вынести и свойство name
class ContactsPage extends Component {
state = {
name: 'Вася'
};
handleGetName = () => this.getName();
// Конструктор в этом случае не требуется
handleGetName() {
alert(this.state.name); // Ожидаем увидеть Васю
}
}
<button onClick={this.handleGetName}>Запустить!</button>
// Еще вариант через синтаксис биндинга ES7 (эксперементальный способ)
constructor(props) {
super(props);
this.getName = ::this.getName; // эквивалент this.getName.bind(this)
}
<button onClick={this.getName}>Запустить!</button>
// А можно оставить конструктор в покое и
<button onClick={::this.getName}>Запустить!</button>
// Последний способ не оптимальный и вызовет проблемы с PureRenderMixin