React: Tratamento de eventos
Última atualização: 2026-10-26
O tratamento de eventos é como as terminações nervosas de um aplicativo React — quando os usuários clicam em botões, digitam texto ou enviam formulários, essas interações são respondidas por meio de eventos. O sistema de eventos do React é mais inteligente e mais unificado do que os eventos nativos do DOM.
1. O que você vai aprender
- A diferença entre eventos compostos do React e eventos nativos Eventos comuns: onClick / onChange / onSubmit / onKeyDown
- Tratamento de objetos de evento
- Passagem de parâmetros para funções de manipulador de eventos
- Impedir o comportamento padrão e a propagação de eventos
2. Uma história sobre a interação com formulários
(1) Pontos críticos: 3 armadilhas no envio de formulários
Bob está criando um formulário de cadastro de usuários e escrevendo manipuladores de eventos em JavaScript nativo:
// Native JS:Various compatibility issues and details need to be handled manually
// 1. Get DOM Element
const form = document.getElementById('register-form')
const nameInput = document.getElementById('name')
const submitBtn = document.getElementById('submit-btn')
// 2. Event Binding
form.addEventListener('submit', function(event) {
event.preventDefault() // Prevent the page from refreshing
// 3. Manually Retrieving Form Data
const formData = new FormData(form)
const data = Object.fromEntries(formData)
// 4. Submit Data
fetch('/api/register', {
method: 'POST',
body: JSON.stringify(data)
})
})
// 5. Real-Time Input Validation
nameInput.addEventListener('input', function(event) {
if (event.target.value.length < 2) {
showError('Name (at least) 2 characters')
} else {
hideError()
}
})
// 6. Prevent duplicate submissions when the Submit button is clicked
let isSubmitting = false
submitBtn.addEventListener('click', function() {
if (isSubmitting) return
isSubmitting = true
submitBtn.disabled = true
submitBtn.textContent = 'Submitting......'
})
O problema do Bob:
- Código disperso: a vinculação de eventos, o processamento de dados e as atualizações da interface do usuário estão espalhados por diferentes locais
- Vazamento de memória: Esquecer de remover os ouvintes de eventos
- Problemas de compatibilidade: Existem diferenças entre as APIs de eventos dos diversos navegadores
(2) Tratamento de eventos no React
▶ ExperimenteBenefícios: O código foi reduzido de 30 linhas para 15 linhas, sem manipulação do DOM, sem problemas de desvinculação de eventos e sem problemas de compatibilidade com navegadores.
3. Eventos compostos do React
Os eventos do React não são eventos nativos do DOM, mas sim SyntheticEvents — o React os monitora no nível superior e simula um sistema de eventos compatível com todos os navegadores.
| Recurso | Eventos nativos do DOM | Eventos compostos do React |
|---|---|---|
| Método de vinculação | addEventListener / onclick |
Escrever diretamente em JSX |
| Compatibilidade com navegadores | Necessidade de tratamento manual das diferenças | Padronização automática |
| Gerenciamento de memória | Os ouvintes devem ser removidos manualmente | Limpeza automática |
| Objeto de evento | Evento nativo | Evento sintético |
| Evitar a formação de bolhas | event.stopPropagation() |
Idêntico (padronizado) |
| Bloqueio padrão | event.preventDefault() |
Igual (padronizado) |
graph TB
A[The user clicks the button] --> B[React Root Node Event Handling]
B --> C[Create a Synthetic Event Object]
C --> D[Simulated Bubbles/Capture Phase]
D --> E[Call JSX Bound to the middle handler]
style B fill:#61dafb,color:#000
style C fill:#1890ff,color:#fff
Saída:
...
Clicked the "Log In" button
Button on Mouse Hover
Mouse leaves button
4. Referência rápida para eventos comuns
| Nome do evento | Condições de acionamento | Cenários comuns | Tipo de objeto do evento |
|---|---|---|---|
onClick |
Elemento clicado | Botão, link, cartão | MouseEvent |
onChange |
Alterações no conteúdo dos campos de entrada | Campos de formulário, menus suspensos | ChangeEvent |
onSubmit |
Enviar formulário | Entrar/Cadastre-se/Pesquisar | FormEvent |
onFocus |
O elemento recebe o foco | O campo de entrada está destacado | FocusEvent |
onBlur |
O elemento perde o foco | Validação de entrada | FocusEvent |
onKeyDown |
Pressione uma tecla | Tecla de atalho, pressione Enter para pesquisar | KeyboardEvent |
onKeyUp |
Imprensa e Comunicados | Pesquisa em tempo real | KeyboardEvent |
onMouseEnter |
Efeito ao passar o mouse | MouseEvent |
|
onMouseLeave |
Efeito ao sair com o mouse | Efeito ao passar o mouse | MouseEvent |
onScroll |
Rolagem | Rolagem infinita | UIEvent |
▶ Exemplo: Visão geral abrangente de eventos comuns
▶ Expandir exemplo executável (81 linhas)
Saída:
Formulário de login com e-mail/senha. E-mail inválido → borda vermelha + "The email address format is incorrect.". Senha com menos de 6 caracteres → "Password must be at least 6 chars". Envio → console.log({email, password})
5. Passagem de parâmetros em eventos
(1) Passagem direta de parâmetros
Envolva-o em uma função-seta e passe os parâmetros adicionais diretamente:
function UserList({ users, onDelete }) {
return (
<ul>
{users.map(user => (
<li key={user.id}>
{user.name}
{/* Arrow Functions:Incoming user.id As an additional parameter */}
<button onClick={() => onDelete(user.id)}>
Delete
</button>
</li>
))}
</ul>
)
}
// Usage
<UserList
users={users}
onDelete={(id) => console.log('Delete User:', id)}
/>
(2) Recuperar tanto o objeto do evento quanto os parâmetros personalizados
function ColorPicker({ colors, onSelect }) {
return (
<div>
<p>Select a Color:</p>
{colors.map(color => (
<button
key={color}
onClick={(event) => {
// event:Native Synthesis Event Object
// color:Custom Parameters
onSelect(color)
console.log('Click here:', event.clientX, event.clientY)
}}
style={{
backgroundColor: color,
width: '40px',
height: '40px',
border: '2px solid #ddd',
borderRadius: '50%',
margin: '4px',
cursor: 'pointer'
}}
/>
))}
</div>
)
}
(3) Três maneiras de passar objetos de evento
| Método | Sintaxe | Cenários aplicáveis |
|---|---|---|
| Passagem implícita | onClick={handleClick} |
Não são necessários parâmetros adicionais |
| Funções-seta | onClick={() => handleClick(id)} |
Requer parâmetros |
| Passar simultaneamente | onClick={(e) => handleClick(e, id)} |
Requer um objeto de evento + parâmetros personalizados |
6. Como evitar o comportamento padrão e a propagação
(1) Impedir o comportamento padrão: preventDefault()
O caso de uso mais comum é impedir que a página seja atualizada quando um formulário é enviado:
▶ Experimente(2) Evitar a formação de bolhas: stopPropagation()
▶ Experimente
7. Exemplo completo: Lista de tarefas (tratamento abrangente de eventos)
▶ Expandir exemplo executável (111 linhas)
Saída:
... ('Log In:', { email, password })
Clicked the "Log In" button
Button on Mouse Hover
Mouse leaves button
Fluxo de interação:
- Digite o nome da tarefa na caixa de texto, pressione Enter ou clique no botão “Adicionar” → A tarefa é adicionada à lista
- Marque a caixa de seleção → Marque a tarefa como concluída (o texto fica riscado e em cinza)
- Clique no botão ✕ → Exclua a tarefa (
stopPropagationpara evitar que um clique duplo acione a função de edição)- Clique duas vezes em qualquer tarefa → É exibida uma caixa de diálogo para edição
▶ Exemplo 2: Atalhos de teclado e gerenciamento do foco
▶ Expandir exemplo executável (95 linhas)
Saída:
Foco automático no campo de entrada. Ctrl+S → "💾 Saved (Ctrl+S)", Ctrl+Z → "↩️ Undo (Ctrl+Z)", Escape → limpa, Enter → "✅ Confirm: [text]". Mostra as teclas pressionadas.
Saída:
Subtítulo: "⌨️ Shortcut Keys Panel". Exibe: "⌨️ Shortcut Keys Panel". Entrada: Type here,Try the shortcut keys.... useEffect gerencia efeitos colaterais. useRef referencia o DOM/variável
▶ Exemplo 3: Tratamento de eventos de classificação por arrastar e soltar
▶ ExperimenteSaída:
4 itens arrastáveis (Apple, Banana, Cherry, Date). Arraste para reordenar; o item arrastado ganha uma borda de destaque azul.
Saída:
Exibe: "Drag to Reorder". Estado: items (setter: setItems), dragIdx (setter: setDragIdx)
▶ Exemplo 4: Hook personalizado para encapsular ouvintes de eventos
▶ ExperimenteSaída:
Hook useEventListener: adiciona/remove automaticamente listeners de eventos do DOM. Limpeza na desmontagem para evitar vazamento de memória
Saída:
Estado: pos (setter: setPos). useEffect gerencia efeitos colaterais. useCallback memoiza o handler
▶ Exemplo 5: Envio de formulário e combinação de eventos
function SearchForm({ onSearch }) {
const [query, setQuery] = useState('')
const [category, setCategory] = useState('all')
function handleSubmit(e) {
e.preventDefault()
onSearch({ query, category })
}
function handleReset() {
setQuery('')
setCategory('all')
}
return (
<form onSubmit={handleSubmit} style={{ maxWidth: 400, margin: '0 auto' }}>
<div style={{ display: 'flex', gap: 8, marginBottom: 8 }}>
<input value={query} onChange={e => setQuery(e.target.value)}
placeholder="Search..." style={{ flex: 1, padding: 8, borderRadius: 4 }} />
<select value={category} onChange={e => setCategory(e.target.value)}
style={{ padding: 8, borderRadius: 4 }}>
<option value="all">All</option>
<option value="electronics">Electronics</option>
<option value="books">Books</option>
</select>
</div>
<div style={{ display: 'flex', gap: 8 }}>
<button type="submit" style={{ padding: '6px 16px', cursor: 'pointer' }}>Search</button>
<button type="button" onClick={handleReset} style={{ padding: '6px 16px', cursor: 'pointer' }}>Reset</button>
</div>
</form>
)
}
Saída:
Barra de busca + menu suspenso de categoria (All/Electronics/Books). A busca envia {query, category}. O reset limpa os dois campos.
❓ Perguntas Frequentes
() => handleClick(id) em vez de simplesmente handleClick(id)?onClick={handleClick(id)} diretamente, o React executará handleClick(id) imediatamente durante a renderização, em vez de esperar até que seja clicado. Isso ocorre porque se trata de uma chamada de função (com parênteses), e não de uma referência à função (sem parênteses). A abordagem correta é onClick={() => handleClick(id)} (função-seta com execução adiada) ou onClick={handleClick} (referenciando diretamente o nome da função quando nenhum argumento é passado).onClick. Soluções: ① Chamar várias funções onClick={() => { fn1(); fn2() }} dentro do mesmo manipulador; ② Ou envolver o elemento com vários HOCs. Normalmente, um elemento precisa apenas de um manipulador de eventos, dentro do qual é possível chamar vários trechos de lógica.SyntheticEvent do React é um wrapper compatível com vários navegadores que envolve os eventos nativos, fornecendo uma API unificada (como e.preventDefault() e e.stopPropagation()) e se comportando de maneira consistente em todos os navegadores. Os eventos sintéticos operam sob um mecanismo de delegação de eventos — todos os eventos são anexados ao nó raiz, em vez de a elementos DOM individuais. No React 17 e versões posteriores, os eventos são delegados à raiz, em vez de ao document, o que evita conflitos quando várias versões do React coexistem.📖 Resumo
- O React usa o SyntheticEvent, que garante compatibilidade entre navegadores e limpeza automática
- Eventos comuns: onClick, onChange, onSubmit, onKeyDown, onFocus/onBlur
- Use funções-seta para passar parâmetros adicionais
onClick={() => handler(id)} event.preventDefault()Impedir o comportamento padrão,event.stopPropagation()Impedir a propagação- Não digite
onClick={handler(id)}(isso será executado imediatamente); em vez disso, useonClick={() => handler(id)}.
📝 Exercícios
- Exercício básico (Dificuldade ⭐): Crie um componente
ButtonCounterque incremente o valor exibido em 1 cada vez que o botão for clicado. Use o eventoonClick. - Exercício avançado (Dificuldade ⭐⭐): Crie um componente
SearchInputque implemente a “busca com supressão de rebote”: a busca é acionada automaticamente 500 ms após o usuário parar de digitar. UseonChangeeuseEffect. - Desafio (Dificuldade: ⭐⭐⭐): Crie um componente
DragAndDropListque implemente a classificação por arrastar e soltar. Utilize os eventosonDragStart,onDragOvereonDrop. Os itens da lista podem ser arrastados para novas posições.