Menu

Eventos no React: onClick, onChange, onSubmit e mais

Eventos no React são props como onClick e onChange que recebem uma função, que o React chama com um objeto de evento quando o usuário age. Aprenda a passar um handler em vez de chamá-lo, passar argumentos, ler e.target.value e e.key, evitar o recarregamento de formulários e impedir a propagação.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

O React trata eventos com props nomeadas a partir do evento em camelCase, como onClick, onChange e onSubmit. Você passa uma função, e o React a chama com um objeto de evento quando o usuário clica, digita ou envia.

Cada clique executa handleClick, que atualiza a contagem e registra no console abaixo da prévia. Experimente onDoubleClick no lugar de onClick: agora só um clique duplo conta.

Passe a função, não a chame

A prop recebe uma função, e o React a chama depois. Um erro muito comum é adicionar parênteses, o que chama a função na hora, durante a renderização, e entrega ao React o valor de retorno dela.

O console mostra "Hi, during render" antes de você tocar em qualquer coisa: o React executou sayHi ao renderizar o primeiro botão e, como sayHi retorna undefined, esse botão não tem handler nenhum. Clicar em Wrong não faz nada. Clicar em Right registra "Hi, Ada", porque a arrow function só executa no clique.

A arrow também é a forma de passar argumentos. onClick={() => removeItem(item.id)} cria uma pequena função para cada item, e essa função chama a sua com o ID certo. Se um handler não recebe argumentos, passe-o pelo nome: onClick={handleClick}.

Com um setter de estado o erro é pior: onClick={setCount(count + 1)} define o estado durante a renderização, o que renderiza de novo, o que define o estado de novo, e o React para com "Too many re-renders".

O objeto de evento

O React passa um argumento para todo handler, o objeto de evento. Ele tem as mesmas propriedades do evento do navegador: e.target é o elemento em que o evento aconteceu, e.key é a tecla pressionada, e.preventDefault() cancela a ação padrão do navegador. O React envolve o evento nativo no que chama de evento sintético, para que ele se comporte igual em todos os navegadores; o original fica em e.nativeEvent se você precisar.

Os dois que você mais usa são e.target.value no onChange e e.key no onKeyDown.

Digite hooks e aperte Enter: a tag é adicionada e o campo é limpo. O console registra cada tecla, inclusive Shift, Backspace e Enter, pelos nomes em e.key. Aperte Escape no meio de uma palavra para descartá-la.

O onChange do React dispara a cada tecla. No HTML puro, o evento change de um campo de texto só dispara quando ele perde o foco, então essa é uma diferença proposital: ela permite que o input e o estado andem juntos letra por letra. Checkboxes dão e.target.checked em vez de value. A página sobre formulários trata de todos os tipos de input.

Formulários e preventDefault

Quando um formulário é enviado, a ação padrão do navegador é enviá-lo e carregar uma nova página. Em um app React você quase sempre quer tratar os dados você mesmo, então o handler de envio começa com e.preventDefault().

Coloque onSubmit no <form>, não onClick no botão: assim apertar Enter no campo também envia, e as verificações próprias do navegador (aqui required e type="email") rodam antes. Apague a linha e.preventDefault() e envie de novo: uma página real agora iria para uma nova página e perderia a mensagem de agradecimento. A prévia bloqueia isso e mostra o que o formulário enviaria, email= sem valor, porque setEmail('') já tinha limpado o campo quando o formulário foi lido.

O React 19 também permite passar uma função para <form action={fn}>, que recebe os dados do formulário e reinicia os campos não controlados para você. A página de formulários mostra os dois estilos.

Bubbling e stopPropagation

A maioria dos eventos sobe (bubbling): depois de rodar no elemento que você clicou, eles rodam no pai dele, depois no pai do pai, até o topo. Os handlers do React seguem a mesma ordem. É por isso que um clique em um botão dentro de um card clicável também conta como clique no card.

Clique em Bubbles up e o console registra o botão, depois o painel interno, depois o card externo. Clique em Stops here e só o botão registra: e.stopPropagation() interrompe a subida. Clicar no texto do próprio painel interno registra o painel e o card.

Use stopPropagation com moderação. Um caso legítimo comum é um botão de excluir dentro de uma linha de lista clicável, em que clicar em excluir não deve também abrir a linha. Se um pai precisa saber se o clique veio de um filho, confira e.target em vez de interromper o evento. Para executar um handler na descida, antes de os filhos verem o evento, o React oferece versões de captura como onClickCapture.

preventDefault e stopPropagation são ferramentas diferentes. A primeira cancela o que o navegador faria (seguir um link, enviar um formulário, marcar um checkbox). A segunda impede que outros handlers fiquem sabendo do evento. Chamar uma não faz a outra.

Outros eventos comuns

O mesmo padrão cobre todos os eventos que o React suporta. Alguns que você vai usar com frequência:

  • onFocus e onBlur disparam quando um input ganha e perde o foco, úteis para mostrar a validação depois que o usuário sai de um campo.
  • onMouseEnter e onMouseLeave disparam quando o ponteiro entra e sai de um elemento. Ao contrário da maioria dos eventos, eles não sobem, então mover o ponteiro de um pai para o filho não dispara de novo o onMouseEnter do pai.
  • onPointerDown, onPointerMove e onPointerUp funcionam igualmente para mouse, toque e caneta, o que os torna a melhor escolha para arrastar.
  • onScroll dispara enquanto um elemento rola. No React ele não sobe.

Cada handler recebe um objeto de evento com as propriedades que fazem sentido para ele: e.clientX para eventos de ponteiro, e.key para eventos de teclado, e.target para todos.

Passando handlers como props

Componentes podem aceitar handlers do pai como qualquer outra prop. Dê a eles nomes onSomething conforme o que aconteceu e chame a função que trata o evento de handleSomething. Isso espelha os eventos embutidos e deixa claro quais props são callbacks.

Stepper não é dono do número; ele informa os cliques e o pai decide o que eles significam. Mude handleDecrement para parar em 1 em vez de 0 e o stepper acompanha sem ser editado. Manter o estado no pai e passar handlers para baixo é o padrão descrito em elevar o estado.

Props de handler personalizadas são só nomes. onIncrement no seu próprio componente não faz nada até que o componente o passe para o onClick de um elemento real, e você pode dar a ele os argumentos que quiser, por exemplo onSelect(item.id).

Perguntas frequentes

Como passo um parâmetro para um handler de onClick?

Envolva a chamada em uma arrow function: onClick={() => deleteItem(item.id)}. A arrow é o que o React chama no clique, e ela então chama a sua função com o argumento.

Por que meu onClick executa quando a página carrega?

Você chamou a função em vez de passá-la. onClick={handleClick()} executa handleClick durante a renderização e passa o valor de retorno. Escreva onClick={handleClick} ou onClick={() => handleClick(id)}.

Qual é a diferença entre o onChange do React e o do HTML?

No HTML, o evento change de um input de texto dispara quando o input perde o foco. O onChange do React dispara a cada tecla, como o evento nativo input, para que o estado acompanhe o texto enquanto ele é digitado.

Como impeço um formulário de recarregar a página no React?

Chame e.preventDefault() no início do handler de onSubmit. Coloque o handler no <form>, não no botão de envio, para que apertar Enter em um campo também envie.

O que é um evento sintético no React?

É o objeto de evento que o React passa para os seus handlers. Ele envolve o evento nativo do navegador com as mesmas propriedades e métodos (target, key, preventDefault(), stopPropagation()) e se comporta igual em todos os navegadores. O original fica disponível em e.nativeEvent.

Ilustração das linguagens de programação do Coddy

Aprenda a programar com o Coddy

COMEÇAR