Ya tenemos componentes. Ahora necesitamos que el usuario pueda interactuar con la interfaz: haciendo clic en botones, escribiendo en formularios o arrastrando elementos.
En React, la gestión de eventos es muy similar al DOM tradicional, pero con algunas diferencias sintácticas y de arquitectura que hacen que nuestro código sea más predecible y compatible entre navegadores.
Sintaxis: React vs HTML
Si venís de escribir HTML clásico, estaréis acostumbrados a esto:
<button onclick="activarLaseras()">Disparar</button>
En React (JSX), hay dos diferencias fundamentales:
- CamelCase: Los eventos se nombran usando camelCase, no minúsculas. Usamos
onClicken vez deonclick,onChangeen vez deonchange, etc. - Funciones, no Strings: En JSX pasamos la función tal cual, no un string con código a ejecutar.
// React (JSX)
function Boton() {
const handleClick = () => {
alert('Pew pew!');
};
return (
<button onClick={handleClick}>
Disparar
</button>
);
}
El error común: Ejecutar vs Referenciar
Fijaos bien en cómo pasamos la función al evento:
- ✅ Correcto (Pasar referencia):
onClick={handleClick} - ❌ Incorrecto (Ejecutar función):
onClick={handleClick()}
Si ponéis los paréntesis (), estáis ejecutando la función inmediatamente cuando React renderiza el componente, no cuando el usuario hace clic.
Eventos más comunes
Aunque React soporta prácticamente todos los eventos del navegador, el 90% del tiempo usaréis estos dos:
Se usa para botones, enlaces y elementos interactivos. Funciona igual que el click nativo.
<button onClick={() => setContador(c => c + 1)}>
Incrementar
</button>
Fundamental para formularios. A diferencia del HTML, donde onchange suele dispararse cuando el input pierde el foco (blur), en React onChange se dispara con cada tecla pulsada.
Esto es importante para mantener sincronizado el estado de React con lo que ve el usuario en tiempo real (lo que llamamos Controlled Components, que veremos más adelante).
const [texto, setTexto] = useState('');
return (
<input
type="text"
value={texto}
onChange={(e) => setTexto(e.target.value)}
/>
);
El objeto SyntheticEvent
En el ejemplo anterior hemos usado un argumento e. ¿Qué es exactamente esa e?
Si inspeccionáis ese objeto en la consola, veréis que no es un evento nativo del DOM. Es un SyntheticEvent.
React implementa su propio sistema de eventos. Es una capa de abstracción (un wrapper) que envuelve al evento nativo del navegador.
Pasando argumentos a los Event Handlers
A menudo, dentro de una lista, querremos pasar un dato específico al handler (por ejemplo, el ID del elemento que queremos borrar).
Como dijimos que no podíamos ejecutar la función directamente. Es decir, no podemos hacer esto
// ❌ Esto no
<button onClick={borrar(id)}>
Eliminar
</button>
Tenemos dos opciones para solucionar esto:
Es la forma más común y moderna. Creamos una función anónima que, al ejecutarse, llama a nuestra función con parámetros.
// ✅ Correcto
<button onClick={() => eliminarUsuario(usuario.id)}>
Eliminar
</button>
Aquí, lo que pasamos a onClick es la definición de la función flecha. React ejecutará esa flecha cuando ocurra el click, y la flecha a su vez ejecutará eliminarUsuario.
Una técnica más funcional, útil si queremos evitar crear arrow functions en cada render (aunque el impacto de rendimiento es despreciable).
const crearHandler = (id) => () => {
eliminarUsuario(id);
};
// Uso
<button onClick={crearHandler(usuario.id)}>Eliminar</button>
Prevent Default
En HTML, si tenéis un formulario y un botón de submit, al hacer clic la página se recargará. En una SPA (Single Page Application) como las que hacemos con React, queremos evitar esa recarga.
Para ello, usamos e.preventDefault().
function Formulario() {
const handleSubmit = (e) => {
// 1. IMPORTANTE: Evitamos la recarga de la página
e.preventDefault();
// 2. Procesamos los datos
console.log('Enviando datos...');
};
return (
<form onSubmit={handleSubmit}>
<button type="submit">Enviar</button>
</form>
);
}
