genbodev
3/15/2018 - 3:41 PM

Вызов функций в компоненте React

// Суть проблемы
// Есть функция 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