Saltar al contenido principal
Logo de JSCamp

Eventos en React

Aprende a manejar eventos en React y cómo hacer que tus componentes respondan a las acciones del usuario

midudev

Más clases y directos en YouTube

Suscribirse

Eventos en React

Hasta ahora nuestros componentes son estáticos: muestran información pero no responden a las acciones del usuario. En esta clase vamos a aprender a manejar eventos como clicks, cambios en inputs, envío de formularios, etc.

¿Qué son los eventos?

Los eventos son acciones que ocurren en el navegador:

  • 👆 Click - El usuario hace clic en un botón
  • ⌨️ Input - El usuario escribe en un input
  • 📝 Change - El valor de un input cambia
  • 📤 Submit - Se envía un formulario
  • 🖱️ Hover - El ratón pasa sobre un elemento

React nos permite escuchar estos eventos y ejecutar código cuando ocurren.

Añadiendo eventos onClick

Vamos a hacer que el botón “Aplicar” responda a clicks. Todavía sin estado, solo vamos a mostrar un mensaje en la consola y una alerta.

Actualiza tu archivo react.html con este código:

function JobCard({ titulo, empresa, ubicacion, descripcion }) {  // Función que se ejecuta al hacer click  const handleAplicar = () => {    console.log('¡Click en el botón!')    console.log('Aplicando a:', titulo, '-', empresa)    alert(`Has aplicado a: ${titulo} en ${empresa}`)  }  return (    <article className="job-listing-card">      <div>        <h3>{titulo}</h3>        <small>          {empresa} | {ubicacion}        </small>        <p>{descripcion}</p>      </div>      <button className="button-apply-job" onClick={handleAplicar}>        Aplicar      </button>    </article>  )}

¿Qué cambió?

Analicemos las novedades paso a paso.

1. Función manejadora de eventos

function JobCard({ titulo, empresa, ubicacion, descripcion }) {  // Definimos una función que se ejecuta al hacer click  const handleAplicar = () => {    console.log('¡Click en el botón!')    console.log('Aplicando a:', titulo, '-', empresa)    alert(`Has aplicado a: ${titulo} en ${empresa}`)  }  return (    <article className="job-listing-card">      {/* ... */}      <button className="button-apply-job" onClick={handleAplicar}>        Aplicar      </button>    </article>  )}

Puntos clave:

  1. Definimos una función handleAplicar dentro del componente
  2. Esta función tiene acceso a las props (titulo, empresa)
  3. Conectamos la función al botón con onClick={handleAplicar}

2. Sintaxis de eventos en React

<button onClick={handleAplicar}>Aplicar</button>

Importante:

  • ✅ Usa camelCase: onClick, no onclick
  • ✅ Pasa la referencia a la función: onClick={handleAplicar}
  • NO la llames: onClick={handleAplicar()} ← Esto ejecuta la función inmediatamente
// ✅ Correcto: pasa la referencia<button onClick={handleAplicar}>Aplicar</button>// ❌ Incorrecto: ejecuta la función inmediatamente<button onClick={handleAplicar()}>Aplicar</button>// ✅ Alternativa con función inline<button onClick={() => alert('Click!')}>Aplicar</button>

Pruébalo

  1. Abre el archivo en tu navegador
  2. Abre la consola (F12 o Cmd+Option+I en Mac)
  3. Haz click en cualquier botón “Aplicar”
  4. Verás los mensajes en la consola y una alerta

Convención de nombres

Por convención, las funciones manejadoras de eventos suelen empezar con handle:

const handleClick = () => {  /* ... */}const handleSubmit = () => {  /* ... */}const handleChange = () => {  /* ... */}const handleAplicar = () => {  /* ... */}

Esto hace el código más legible: cuando ves handleAlgo, sabes que es un manejador de eventos.

Comparación con JavaScript vanilla

Veamos cómo hemos simplificado el manejo de eventos.

Antes (JavaScript vanilla)

En nuestro archivo apply-button.js teníamos que hacer esto:

const jobsListingSection = document.querySelector('.jobs-listings')jobsListingSection.addEventListener('click', function (event) {  const element = event.target  if (element.classList.contains('button-apply-job')) {    element.textContent = '¡Aplicado!'    element.classList.add('is-applied')    element.disabled = true  }})

Problemas:

  • Event delegation - Tenemos que escuchar en un contenedor padre
  • Verificar el target - Con if (element.classList.contains(...))
  • Manipular el DOM manualmente - Cambiar texto, clases, etc.
  • Código difícil de mantener - Todo mezclado

Ahora (React)

const handleAplicar = () => {  alert(`Has aplicado a: ${titulo} en ${empresa}`)};<button onClick={handleAplicar}>Aplicar</button>

Ventajas:

  • Directo - El evento está donde lo necesitas
  • Sin querySelector - No buscas elementos
  • Sin addEventListener - React lo hace por ti
  • Sin event delegation - Cada componente gestiona sus eventos
  • Acceso a props - La función tiene acceso al contexto del componente

¡Mucho más simple!

Eventos con funciones inline

A veces es útil definir la función directamente en el onClick:

function JobCard({ titulo, empresa }) {  return <button onClick={() => alert(`Aplicando a ${titulo}`)}>Aplicar</button>}

¿Cuándo usar cada enfoque?

Función separada (recomendado)

function JobCard({ titulo }) {  const handleClick = () => {    console.log('Click!')    alert(titulo)  }  return <button onClick={handleClick}>Aplicar</button>}

Mejor cuando:

  • La función tiene más de una línea
  • Quieres reutilizar la función
  • Necesitas testear la función

Función inline

<button onClick={() => alert('Click!')}>Aplicar</button>

Mejor cuando:

  • Es una sola línea muy simple
  • No se va a reutilizar

Acceso a las props en los manejadores

Los manejadores de eventos tienen acceso completo a las props del componente:

function JobCard({ titulo, empresa, ubicacion, descripcion }) {  const handleAplicar = () => {    // Podemos usar todas las props    console.log('Título:', titulo)    console.log('Empresa:', empresa)    console.log('Ubicación:', ubicacion)    console.log('Descripción:', descripcion)    alert(`Has aplicado a ${titulo} en ${empresa}`)  }  return (    <article>      <h3>{titulo}</h3>      <button onClick={handleAplicar}>Aplicar</button>    </article>  )}

Esto es posible gracias a los closures de JavaScript: la función handleAplicar “recuerda” las variables del ámbito donde fue creada.

Tipos de eventos comunes

React soporta todos los eventos del navegador. Los más comunes:

onClick - Click del ratón

<button onClick={() => console.log('Click!')}>Haz click</button>

onChange - Cambio en un input

<input onChange={(e) => console.log('Valor:', e.target.value)} />

onSubmit - Envío de formulario

<form  onSubmit={(e) => {    e.preventDefault()    console.log('Formulario enviado')  }}>  <button type="submit">Enviar</button></form>

onMouseEnter / onMouseLeave - Hover

<div onMouseEnter={() => console.log('Entrando')} onMouseLeave={() => console.log('Saliendo')}>  Pasa el ratón</div>

onKeyDown / onKeyUp - Teclas

<input onKeyDown={(e) => console.log('Tecla:', e.key)} />

El objeto evento (event)

Los manejadores de eventos reciben un objeto evento como parámetro:

function JobCard({ titulo }) {  const handleAplicar = (event) => {    console.log('Evento completo:', event)    console.log('Elemento que disparó el evento:', event.target)    console.log('Tipo de evento:', event.type)  }  return <button onClick={handleAplicar}>Aplicar</button>}

Propiedades útiles del evento

const handleClick = (event) => {  event.preventDefault() // Prevenir comportamiento por defecto  event.stopPropagation() // Detener propagación del evento  event.target // Elemento que disparó el evento  event.currentTarget // Elemento al que está adjunto el evento  event.type // Tipo de evento ('click', 'change', etc.)}

Ejemplo práctico con preventDefault

function Formulario() {  const handleSubmit = (event) => {    event.preventDefault() // Evita recargar la página    console.log('Formulario enviado')  }  return (    <form onSubmit={handleSubmit}>      <input type="text" placeholder="Nombre" />      <button type="submit">Enviar</button>    </form>  )}

Pasando argumentos a los manejadores

¿Qué pasa si necesitas pasar argumentos adicionales?

Opción 1: Función inline con arrow function

function JobCard({ titulo, id }) {  const handleAplicar = (jobId) => {    console.log('ID del empleo:', jobId)  }  return <button onClick={() => handleAplicar(id)}>Aplicar</button>}

Opción 2: Con el evento

function JobCard({ titulo, id }) {  const handleAplicar = (event, jobId) => {    console.log('Evento:', event)    console.log('ID del empleo:', jobId)  }  return <button onClick={(e) => handleAplicar(e, id)}>Aplicar</button>}

Múltiples eventos en un componente

Puedes tener varios manejadores en el mismo componente:

function JobCard({ titulo, empresa }) {  const handleAplicar = () => {    alert(`Aplicando a ${titulo}`)  }  const handleGuardar = () => {    alert(`Guardando ${titulo}`)  }  const handleCompartir = () => {    alert(`Compartiendo ${titulo}`)  }  return (    <article>      <h3>{titulo}</h3>      <button onClick={handleAplicar}>Aplicar</button>      <button onClick={handleGuardar}>Guardar</button>      <button onClick={handleCompartir}>Compartir</button>    </article>  )}

Limitaciones actuales

Por ahora, cuando hacemos click en “Aplicar”:

  • ✅ Se ejecuta la función
  • ✅ Se muestra la alerta
  • ✅ Se imprime en consola
  • ❌ El botón NO cambia visualmente
  • ❌ No se recuerda que aplicaste

¿Por qué?

Porque todavía no estamos usando estado. El componente no “recuerda” nada entre renders.

En la próxima clase aprenderemos sobre useState, que nos permitirá:

  • Cambiar el texto del botón a “¡Aplicado!”
  • Desactivar el botón después de aplicar
  • Añadir una clase CSS
  • ¡Y mucho más!

Lo que hemos aprendido de los eventos de React

  • 🎯 Qué son los eventos en React
  • 👆 Sintaxis de eventos - onClick, onChange, etc.
  • 🔧 Crear manejadores - Funciones que responden a eventos
  • 📦 Acceso a props - Los manejadores pueden usar las props
  • Comparación con vanilla JS - Mucho más simple
  • 🎨 Diferentes tipos de eventos - Click, change, submit, hover, etc.
  • 📝 Objeto evento - Acceder a información del evento
  • 🔀 Múltiples eventos - Varios manejadores en un componente

En la próxima clase aprenderemos sobre el estado con useState, que nos permitirá crear componentes que cambian en respuesta a eventos.

💡 Recuerda: Los eventos en React usan camelCase (onClick) y reciben referencias a funciones, no llamadas (onClick={handleClick}, no onClick={handleClick()}).