React

React

Tutorial React: Eventos en React

React Eventos en React: Aprende a manejar eventos, sintaxis, y eventos sintéticos para crear aplicaciones interactivas y optimizadas en React.

¿Qué son los eventos en React?

En React, los eventos son objetos que representan interacciones del usuario con la interfaz de usuario, como clics de ratón, pulsaciones de teclas y movimientos del ratón, entre otros. 

Los eventos en React se basan en el sistema de eventos del DOM, pero presentan ciertas diferencias y mejoras para facilitar su uso y optimización en aplicaciones React.

Sintaxis y manejo de eventos en React

Los eventos se manejan con la notación camelCase en lugar de minúsculas. 

  • En HTML: se pasa una cadena de texto con la invocación de una función. Ejemplo de un evento de clic:
<button onclick="handleClick()">Click me</button>
  • En React: se pasa el nombre de la función directamente como manejador del evento. Ejemplo de un evento de clic equivalente en React:
<button onClick={handleClick}>Click me</button>

Eventos sintéticos

React utiliza un sistema de eventos sintéticos (Synthetic Events) que es una capa de abstracción sobre los eventos del navegador. 

Los Synthetic Events garantizan que los eventos se comporten de manera consistente en todos los navegadores, lo que facilita la escritura de código compatible entre diferentes entornos.

Ejemplo de un evento sintético en React:

// SyntheticEvent.jsx
export default function SyntheticEvent() {
    function handleClick(event) {
        console.log(event.type); // "click"
    }

    return (
        <button onClick={handleClick}>Click me</button>
    )
}

Propiedades y métodos del evento

Los Synthetic Events en React tienen las mismas propiedades y métodos que los eventos nativos del navegador. Además, React optimiza el rendimiento mediante la reutilización de objetos de eventos a través de un sistema de agrupación (pooling). 

Sin embargo, esto significa que las propiedades del evento se anulan inmediatamente después de que se ejecuta el manejador del evento. Para acceder a las propiedades del evento de manera asíncrona, es posible utilizar event.persist().

Ejemplo de uso de event.persist():

export default function Boton() {
  function handleClick(event) {
    event.persist();
    setTimeout(() => {
      alert(event.type); // "click"
    }, 1000);
  }
  return (
    <button onClick={handleClick}>Click me</button>
  )
}

Ejemplo práctico

A continuación, se muestra un ejemplo práctico de cómo manejar un evento de clic en React utilizando una variable local para mostrar un mensaje de confirmación en respuesta a la interacción del usuario:

// ClickMessage.jsx
export default function ClickMessage() {
    function handleClick() {
        console.log('Button clicked!');
        alert('¡Has hecho clic en el botón!');
    }

    return (
        <div>
            <p>Haz clic en el botón para ver un mensaje:</p>
            <button onClick={handleClick}>Click me</button>
        </div>
    );
}

En este ejemplo, definimos una función handleClick que se ejecuta cada vez que se hace clic en el botón. Dentro de handleClick, se registra un mensaje en la consola y se muestra una alerta con un mensaje de confirmación.

Eventos de clic y eventos de formulario

En React, los eventos de clic y los eventos de formulario son esenciales para interactuar con la interfaz de usuario y gestionar las entradas del usuario. Los eventos de clic se utilizan para manejar interacciones como hacer clic en botones o enlaces, mientras que los eventos de formulario se utilizan para gestionar entradas en formularios, como el envío de datos o la validación de campos.

Para manejar un evento de clic en React, se asigna un manejador de eventos a un elemento utilizando la propiedad onClick. Este manejador es una función que se ejecuta cuando ocurre el evento de clic. A continuación, se muestra un ejemplo básico de cómo manejar un evento de clic en un botón:

// ClickButton.jsx
export default function ClickButton() {
    function handleClick() {
        alert('Button clicked!');
    }
    return (
        <button onClick={handleClick}>Click me</button>
    );
}

En este ejemplo, cuando se hace clic en el botón, se ejecuta la función handleClick, que muestra una alerta con un mensaje de confirmación.

Los eventos de formulario son igualmente importantes y se manejan de manera similar. Para gestionar el envío de un formulario, se utiliza el evento onSubmit. Es fundamental prevenir el comportamiento predeterminado del envío del formulario, que recarga la página, utilizando event.preventDefault(). Aquí hay un ejemplo de cómo manejar el envío de un formulario en React:

// Formulario.jsx
import { useState } from 'react';

export default function Formulario() {
    const [inputValue, setInputValue] = useState('');

    function capturarEnvio(event) {
        event.preventDefault();
        console.log('Formulario enviado:', inputValue);
    }

    function capturarCambio(event) {
        setInputValue(event.target.value);
    }

    return (
        <form onSubmit={capturarEnvio}>
            <label>
                Input:
                <input type="text" value={inputValue} onChange={capturarCambio} />
            </label>
            <button type="submit">Submit</button>
        </form>
    );
}

En este ejemplo, el componente Form gestiona el estado del valor del input utilizando el hook useState. La función handleChange actualiza el estado cada vez que el usuario escribe en el campo de texto. Cuando el formulario se envía, la función handleSubmit se ejecuta, previene el comportamiento predeterminado y registra el valor del input en la consola.

Además de onSubmit, existen otros eventos de formulario que son útiles, como onChange para manejar cambios en los campos de entrada y onFocus y onBlur para gestionar el enfoque y desenfoque de los elementos del formulario. Aquí hay un ejemplo que muestra cómo manejar varios eventos de formulario:

// MultiplesEventosFormulario.jsx
import { useState } from 'react';

export default function MultiplesEventosFormulario() {
    const [inputValue, setInputValue] = useState('');
    const [isFocused, setIsFocused] = useState(false);

    function handleChange(event) {
        setInputValue(event.target.value);
    }

    function handleFocus() {
        setIsFocused(true);
    }

    function handleBlur() {
        setIsFocused(false);
    }

    function handleSubmit(event) {
        event.preventDefault();
        console.log('Formulario enviado:', inputValue);
    }

    return (
        <form onSubmit={handleSubmit}>
            <label>
                Input:
                <input
                    type="text"
                    value={inputValue}
                    onChange={handleChange}
                    onFocus={handleFocus}
                    onBlur={handleBlur}
                />
            </label>
            <button type="submit">Submit</button>
            {isFocused && <p>Input is focused</p>} {/* muestra un mensaje si el input tiene el foco */}
        </form>
    );
}

En este ejemplo, la función handleFocus establece el estado isFocused en true cuando el input está enfocado y handleBlur lo establece en false cuando el input pierde el enfoque. Esto permite mostrar un mensaje adicional cuando el input está activo.

Argumentos en eventos y prevenir comportamiento predeterminado

En React, los manejadores de eventos pueden recibir argumentos adicionales además del propio evento. Esto es útil cuando se necesita pasar información adicional al manejador de eventos. La forma más común de hacerlo es utilizando una función de flecha para envolver el manejador del evento.

Ejemplo de cómo pasar argumentos adicionales a un manejador de eventos:

// BotonEvento.jsx
export default function BotonEvento({ id }) {
  function handleClick(id, event) {
    console.log('Botón clickeado con id:', id);
    console.log('Tipo de evento:', event.type);
  }

  return (
    <button onClick={(event) => handleClick(id, event)}>
      Clicame
    </button>
  );
}

En este ejemplo, la función handleClick recibe tanto el argumento id como el objeto event. Al hacer clic en el botón, se imprimirá el id del botón y el tipo de evento en la consola.

Además de pasar argumentos, es fundamental en muchas situaciones prevenir el comportamiento predeterminado de los eventos.

En este ejemplo, handleClick previene el comportamiento predeterminado del enlace utilizando event.preventDefault(). puedes tener un enlace que, en lugar de navegar a una nueva página, realiza una acción específica en la aplicación.

Ejemplo de cómo prevenir el comportamiento predeterminado en un enlace:

// Link.jsx
export default function Link() {
    function handleClick(event) {
        event.preventDefault();
        console.log('Link clickeado, pero navegación prevista.');
    }

    return (
        <a href="https://example.com" onClick={handleClick}>
            Click me
        </a>
    );
}

En este ejemplo, al hacer clic en el enlace, handleClick previene la navegación predeterminada utilizando event.preventDefault(), y en su lugar, imprime un mensaje en la consola.

El manejo de argumentos en eventos y la prevención del comportamiento predeterminado son técnicas esenciales para controlar las interacciones del usuario y la lógica de la aplicación en React. Utilizando estas técnicas, se puede crear una experiencia de usuario más fluida y personalizada.

Propagación de eventos

En React, la propagación de eventos sigue un modelo similar al del DOM nativo, donde los eventos pueden propagarse a través de una fase de captura y una fase de burbujeo. Sin embargo, React implementa su propio sistema de eventos sintéticos, lo que permite un manejo más consistente y unificado de los eventos en diferentes navegadores.

Fase de burbujeo y fase de captura

Los eventos en React pueden propagarse a través de dos fases:

  1. Fase de captura: El evento se propaga desde el elemento raíz hacia el elemento objetivo.
  2. Fase de burbujeo: El evento se propaga desde el elemento objetivo hacia el elemento raíz.

Por defecto, React maneja los eventos en la fase de burbujeo. Sin embargo, es posible especificar que un evento debe ser manejado en la fase de captura utilizando el prefijo on seguido de Capture.

Ejemplo de manejo de eventos en ambas fases:

// MiEventoCaptureBurbujeo.jsx
export default function MiEventoCaptureBurbujeo() {
    function manejarClickCaptura(event) {
        console.log('Fase de captura: ', event.target);
    }

    function manejarClickBurbujeo(event) {
        console.log('Fase de burbujeo: ', event.target);
    }

    return (
        <div onClickCapture={manejarClickCaptura} onClick={manejarClickBurbujeo}>
            <button>Clic aquí</button>
        </div>
    );
}

En este ejemplo, manejarClickCaptura se ejecutará durante la fase de captura y manejarClickBurbujeo durante la fase de burbujeo. Al hacer clic en el botón, primero se registrará la fase de captura y luego la fase de burbujeo.

Detener la propagación de eventos

Es posible detener la propagación de un evento en cualquier fase utilizando el método event.stopPropagation(). Esto es útil para evitar que un evento manejado en un componente hijo se propague a un componente padre.

Ejemplo de detener la propagación de eventos:

// PropagacionEvento.jsx
export default function PropagacionEvento() {
    function manejarClick(event) {
        event.stopPropagation();
        console.log('El botón fue clickeado y la propagación detenida');
    }

    function manejarClickPadre() {
        console.log('El contenedor fue clickeado');
    }

    return (
        <div onClick={manejarClickPadre}>
            <button onClick={manejarClick}>Clic aquí</button>
        </div>
    );
}

En este ejemplo, al hacer clic en el botón, manejarClick detiene la propagación del evento, por lo que manejarClickPadre no se ejecutará.

Contexto this en eventos

En React, el contexto this en los eventos es un aspecto crucial para entender cómo funcionan los manejadores de eventos dentro de los componentes de clase. En los componentes funcionales, este problema se mitiga mediante el uso de hooks, pero sigue siendo relevante en componentes de clase.

Cuando se define un manejador de eventos en un componente de clase, el contexto this dentro de la función manejadora no está automáticamente vinculado al componente. Esto puede llevar a errores donde this es undefined o no apunta al componente esperado.

Métodos para vincular this en manejadores de eventos

Enlazar en el constructor: Esta es la forma más común y recomendada. Se enlaza el contexto this del componente al manejador de eventos en el constructor del componente.

// BindInConstructor.jsx
import { Component } from 'react';

export default class BindInConstructor extends Component {
    constructor(props) {
        super(props);
        this.manejarClick = this.manejarClick.bind(this);
    }

    manejarClick() {
        console.log('El botón fue clickeado por', this);
    }

    render() {
        return (
            <button onClick={this.manejarClick}>
                Clic aquí
            </button>
        );
    }
}

Propiedades de clase con funciones flecha: Las funciones flecha no tienen su propio contexto this; en su lugar, heredan el contexto this de su contexto envolvente. Esto elimina la necesidad de enlazar explícitamente this.

// BindArrowFunc.jsx
import { Component } from 'react';

export default class BindArrowFunc extends Component {
    manejarClick = () => {
        console.log('El botón fue clickeado por', this);
    }

    render() {
        return (
            <button onClick={this.manejarClick}>
                Clic aquí
            </button>
        );
    }
}

Enlazar directamente en el render: Aunque es posible, esta técnica no es recomendada debido a que crea una nueva función en cada renderizado, lo que puede tener implicaciones en el rendimiento.

// BindInRender.jsx
import { Component } from 'react';

export default class BindInRender extends Component {
    manejarClick() {
        console.log('El botón fue clickeado por', this);
    }

    render() {
        return (
            <button onClick={this.manejarClick.bind(this)}>
                Clic aquí
            </button>
        );
    }
}
Certifícate en React con CertiDevs PLUS

Ejercicios de esta lección Eventos en React

Evalúa tus conocimientos de esta lección Eventos en React con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Todas las lecciones de React

Accede a todas las lecciones de React y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Certificados de superación de React

Supera todos los ejercicios de programación del curso de React y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender qué son y cómo funcionan los eventos en React.
  • Manejar eventos usando la sintaxis de React.
  • Utilizar eventos sintéticos para garantizar la compatibilidad entre navegadores.
  • Gestionar la propagación de eventos y detenerla cuando sea necesario.
  • Controlar el contexto this en los eventos dentro de los componentes de clase.
  • Implementar eventos de clic y eventos de formulario en aplicaciones React.