Обработка событий в React
Обработка событий с элементами React очень похожа на обработку событий на элементах DOM. Существуют синтаксические различия:
- React events вызываются с помощью с помощью camelCase, а не в нижнем регистре.
- С JSX вы передаете функцию как обработчик события, а не строку.
Например в HTML:
<button onclick="activateLasers()">
Activate Lasers
</button>
Аналогично в React:
<button onClick={activateLasers}>
Activate Lasers
</button>
Другое отличие состоит в том, что вы не можете вернуть false, чтобы предотвратить поведение по умолчанию в 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, поэтому вам не нужно беспокоиться о совместимости между браузерами.
При использовании React вам обычно не нужно вызывать addEventListener
, чтобы добавить слушателей в элемент DOM после его создания. Вместо этого просто предоставляйте слушателю, когда элемент изначально отображается.
Когда вы определяете компонент с использованием класса 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(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
Вы должны быть осторожны со значением this
в обратных вызовах JSX. В JavaScript методы класса не связаны по умолчанию. Если вы забудете связать this.handleClick
и передать его onClick
, this
будет неопределенным, когда функция фактически вызывается.
Это не относится к конкретному поведению; это часть того, как функции работают в JavaScript. Как правило, если вы ссылаетесь на метод без ()
после него, например onClick = {this.handleClick}
, вы должны связать этот метод.
Если вызов bind
раздражает вас, есть два способа обойти это. Если вы используете синтаксис полей экспериментального открытого класса, вы можете использовать поля классов для правильного привязки обратных вызовов: