Edit on GitHub

Manipulando eventos

Manipular eventos de elementos do React é muito parecido com manipular eventos de elementos do DOM. Existem algumas diferenças de sintaxe:

  • Eventos do React são nomeados usando camelCase, ao invés de lowercase.
  • Com JSX você passa uma função como o manipulador do evento, ao invês de uma string.

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')
);

Teste este código no CodePen.

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.