Manipular eventos de elementos do React é muito parecido com manipular eventos de elementos do DOM. Existem algumas diferenças de sintaxe:
Por exemplo, em HTML:
<button onclick="activateLasers()">
Activate Lasers
</button>
é levemente diferente com React:
<button onClick={activateLasers}>
Activate Lasers
</button>
Outra diferença é que você não pode retornar false
para prevenir o comportamento padrão(prevent default) em React. Você deve chamar preventDefault
explicitamente. Por exemplo, com HTML puro, para prevenir o comportamento padrão de um link para abrir uma nova página, você pode escrver:
<a href="#" onclick="console.log('The link was clicked.'); return false">
Click me
</a>
Em React, isto poderia ser:
function ActionLink() {
function handleClick(e) {
e.preventDefault();
console.log('The link was clicked.');
}
return (
<a href="#" onClick={handleClick}>
Click me
</a>
);
}
Aqui, e
é um evento sintético. React define estes eventos sintéticos de acordo com a especificação da W3C, então você não precisa se preocupar com compatibilidade entre browsers. Veja o guia de referência SyntheticEvent
para aprender mais.
Ao usar React você geralmente não precisará chamar addEventListener
para adicionar ouvintes(listeners) para um elemento do DOM depois que ele é criado. Em vez disso, basta fornecer um ouvinte quando o elemento é renderizado incialmente.
Quando você define um componente usando uma classe ES6 , um padrão comum é para um manipulador de evento(event handler) ser um método na classe. Por exemplo, este componente Toggle
renderiza um botão que permite ao usuário alterar o estado entre "ON" e "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')
);
Você precisa ser cuidadoso sobre o significado de this
em callbacks do JSX. Em JavaScript, métodos de classes não são vinculados por padrão. Se você esquecer de vincular this.handleClick
e passá-lo para onClick
, this
será undefined
quando a função for realmente chamada.
Este não é um comportamente específico do React; é parte de como as funções funcionam em JavaScript JavaScript. Geralmente, se você se refere a um método sem o ()
depois dele, como em onClick={this.handleClick}
, você deve vincular esse método.
Se chamar bind
irrita você, existem duas maneiras de contornar isso. Se você estiver usando a
sintaxe de inicialização de propriedade, você pode usar inicializadores para vincular corretamente os callbacks:
class LoggingButton extends React.Component {
// This syntax ensures `this` is bound within handleClick.
// Warning: this is *experimental* syntax.
handleClick = () => {
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
Esta sintaxe é habilitada por padrão em Crie uma aplicação React.
Se você não esta usando a sintaxe de inicialização de propriedade, você pode usar uma arrow function no seu callback:
class LoggingButton extends React.Component {
handleClick() {
console.log('this is:', this);
}
render() {
// This syntax ensures `this` is bound within handleClick
return (
<button onClick={(e) => this.handleClick(e)}>
Click me
</button>
);
}
}
O problema com essa sintaxe é que um callback diferente é criado toda vez que LogginButton
é renderizado. Na maioria dos casos, não tem problema com isso. No entanto, se o callback é passado como propriedade(prop) para um um componente abaixo, estes componentes podem fazer uma re-renderização extra. Nós geralmente recomendamos fazer o vínculo(binding) no construtor para evitar esse tipo de problema de desempenho.