Skip to content
This page has been auto-translated and may contain errors.View in English

Eventos

Você construiu um botão. Agora ele precisa fazer algo de verdade quando alguém clica nele, salvar um formulário, abrir um menu, deletar um item. React lida com isso da mesma forma que lida com tudo mais: através de props. Em vez de chamar addEventListener como você fez no capítulo de eventos do JavaScript, você passa uma função diretamente para uma prop no elemento que quer escutar. A ideia é a mesma — uma função que executa quando algo acontece — mas a forma de conectar tudo é um padrão React específico.

Anexando um manipulador

jsx
function SaveButton() {
  function handleClick() {
    console.log('clicado')
  }
  return <button onClick={handleClick}>Salvar</button>
}

Props de eventos são nomeadas em camelCase, correspondendo ao evento que escutam: onClick para cliques, onChange para mudanças no valor de um campo, onSubmit para envio de formulário. Você escreve a prop no elemento e atribui uma função para executar.

handleClick é definida dentro do componente e passada para onClick. React a chama sempre que o botão é clicado. Você está passando a função pelo nome, handleClick. Chamá-la, handleClick(), a executaria imediatamente, durante a renderização. Você está entregando a função para React executar depois, não executando ela mesmo agora.

Quando você precisa de detalhes sobre o que aconteceu, React passa para seu manipulador um objeto de evento com as mesmas propriedades familiares que você esperaria de addEventListener, como target, preventDefault() e assim por diante. Nomeie um parâmetro para capturá-lo, convencionalmente event:

jsx
function SearchBox() {
  function handleChange(event) {
    console.log(event.target.value)
  }
  return <input onChange={handleChange} />
}

event.target é o elemento em que o evento disparou, e event.target.value é o texto atual no campo. Você só precisa chegar ao objeto de evento quando um manipulador realmente precisa dessa informação. O onClick de um botão frequentemente não precisa.

O erro mais comum

Como o manipulador é uma função que você está entregando a uma prop, este é um erro que pega quase todo mundo em algum momento:

jsx
// Errado: executa handleClick imediatamente, enquanto o componente renderiza
<button onClick={handleClick()}>Salvar</button>

// Correto: passa a função em si, React a chama depois, no clique
<button onClick={handleClick}>Salvar</button>

Os parênteses fazem toda a diferença. handleClick() executa a função bem ali, durante a renderização, e tudo que ela retorna (geralmente undefined) é o que acaba em onClick. handleClick entrega a função em si para React chamar sempre que o clique realmente acontecer. Se um manipulador parece disparar sozinho assim que a página carrega, quase sempre é por isso.

Passando manipuladores como props

Um manipulador não precisa viver no mesmo componente que o elemento em que está anexado. Você pode defini-lo em um componente pai e passá-lo para um filho como uma prop, da mesma forma que passaria qualquer outro valor:

jsx
function SaveButton({ onSave }) {
  return <button onClick={onSave}>Salvar</button>
}

function Form() {
  function handleSave() {
    console.log('salvo')
  }
  return <SaveButton onSave={handleSave} />
}

Form é dona de handleSave e a passa para SaveButton sob o nome de prop onSave. SaveButton não sabe nem se importa com o que a função faz, ela apenas a conecta a onClick. É assim que um clique em um componente pequeno e reutilizável acaba disparando lógica que vive mais acima na sua aplicação, mais perto do state ou dos dados que essa lógica precisa.

Prevenindo o comportamento padrão

Alguns eventos vêm com comportamento do navegador anexado, e enviar um formulário é o que você encontrará primeiro. Por padrão, enviar um formulário recarrega a página, o que destrói tudo o que seu componente estava fazendo. Chame event.preventDefault() dentro do manipulador para parar isso:

jsx
function SignupForm() {
  function handleSubmit(event) {
    event.preventDefault()
    console.log('formulário enviado')
  }
  return (
    <form onSubmit={handleSubmit}>
      <input type="email" />
      <button type="submit">Se inscrever</button>
    </form>
  )
}

Anexe onSubmit ao <form> em si, não onClick ao botão. Assim pressionar Enter dentro do campo também envia o formulário, não apenas clicar no botão.

O objeto de evento que React passa para você não é o evento nativo do navegador. É um invólucro que React constrói ao seu redor, normalizando as diferenças entre navegadores para que o mesmo código funcione em todos sem você verificar qual navegador disparou o evento. Ele traz as propriedades que você esperaria, target, preventDefault(), key e assim por diante, mas é o próprio objeto do React.

React também não anexa um listener a cada elemento que tem uma prop onClick ou onChange. Ele anexa um listener único na raiz da sua aplicação e usa event bubbling para descobrir qual manipulador do componente deve ser executado para um determinado evento. É por isso que o tratamento de eventos funciona da mesma forma para elementos que ainda não existem quando a aplicação é renderizada pela primeira vez — um item adicionado a uma lista depois ainda dispara seu onClick corretamente, porque o listener na raiz nunca foi vinculado a esse elemento específico em primeiro lugar.

JunoManipuladores são funções em props Props de eventos são nomeadas como onClick e onChange, e você atribui uma função para executar, não o resultado de executá-la. Escreva onClick={handleClick}, nunca onClick={handleClick()}. Quando um manipulador precisa de detalhes sobre o que aconteceu, capture-os com um parâmetro nomeado event.
JunoManipuladores são funções em props Anexe manipuladores com props em camelCase como onClick, onChange e onSubmit, e passe a referência da função, não uma chamada para ela. Defina um manipulador em um componente pai e passe-o para um filho como uma prop quando a lógica pertence mais acima. E chame event.preventDefault() em um manipulador de envio, ou a página recarrega e você perde seu state.
JunoManipuladores são funções em props O objeto de evento do React é um invólucro sintético sobre o nativo, normalizado entre navegadores, e React anexa um listener único na raiz em vez de um por elemento, confiando em bubbling para rotear o evento para o manipulador correto. A regra do dia a dia ainda se mantém: entregue a função para React, não a chame você mesmo, e recorra a event.preventDefault() no onSubmit de um formulário para assumir o controle da navegação padrão do navegador.

Próximo: Renderização condicional, onde o que um componente retorna começa a depender dos dados que ele tem.