⚛ Uniendo los puntos: cómo lograr la reactividad usando eventos y estado en React.js

Introducción

Dentro del ecosistema de React, para conseguir la reactividad, es decir, que los elementos cambien de manera dinámica según una acción del usuario como por ejemplo un clic o escribir en un input, es necesario entender bien los conceptos de receptor de eventos, funciones manejadoras de eventos (event handlers) y estado. En este artículo usaremos ejemplos sencillos, que pueden servir de punto de partida para comprender la integración de eventos, estados y formulario.

Antes de proseguir al artículo, es necesario tener los siguientes conocimientos, sobre los cuales también tengo artículos en profundidad:

  1. Eventos y manejadores de eventos (Obligatório)

  2. El concepto y uso de estado (Obligatório)

  3. Desestructuración de arreglos (Obligatório)

  4. Qué es y como funciona el DOM (Recomendable)

Antes de empezar me gustaría definir y determinar a qué me refiero con receptor de eventos y funciones manejadoras. Llamaré receptor de eventos a todos los event listeners como OnClick y onChange, los cuales se declaran como atributos de un elemento JSX. A las funciones vinculadas a esos eventos las llamaré funciones manejadoras. Por ejemplo:

const miFuncion = () => {
}

<input type="text" onChange={miFuncion} /> 
//El evento sería onChange y la función manejadora seria miFuncion

Recibiendo a un evento

El primer punto que desencadena una reactividad empieza cuando se detecta una acción a través de un evento. En React, debido a JSX, es muy fácil añadir un receptor de eventos**,** visto que podemos podemos acceder a los atributos que nos son expuestos por React en cada elemento JSX . Como por ejemplo los atributos onChange y onClick por citar los más comunes. A estos atributos les asignamos una función, que recibirá automáticamente el objeto de evento y una vez recibamos este podemos acceder a su valor.

const App = () => {

  const funcionManejadora = (event) => {
    console.log(event.target.value);
  };

  return (
    <div>
      <form>
        <div>
          <label>Titulo</label>
          <input type="text" onChange={funcionManejadora} />
        </div>
        <button type="submit">Add</button>
      </form>
    </div>
  );
};

export default App;

De las propiedades disponibles en el objeto de evento (el cual se pasa de manera automática del navegador a la función manejadora), nos interesa .target.value, que es la que nos devuelve el valor del input (que será lo que se haya escrito en el campo). Si hubiera escrito “prueba” en el input del ejemplo, en la consola hubiera aparecido:

Usando eventos y estado

Cada vez que queramos modificar algún valor que se muestre en pantalla o recibir los valores desde un formulario y luego mostrarlo, debemos usar en conjunto los eventos, funciones manejadoras y el estado.

Visto que las variables normales en React.js no son capaces de disparar una re-evaluación de un componente , necesitamos usar el método useState de React para ello. Este nos proporcionará un tipo de variable especial que sí informará a React que el componente debe ser re-evaluado, actualizando así la información en la IU de forma dinámica. Este método nos da un array con una propiedad y un método:

  1. Variable de estado

  2. Función de estado

Para acceder a estas más fácilmente podemos usar la desestructuración de array. Cada vez que queramos actualizar la variable de estado debemos hacerlo a través de la función de estado y no directamente. Normalmente se ejecuta esta función dentro de la función manejadora, dado que se disparará según la acción que haya realizado el usuario como por ejemplo un clic.

React maneja el “historial” de estados independientemente, lleva un registro de los estados, por lo que aunque el componente sea reevaluado, podemos acceder al último valor del estado y no a su valor inicial. El valor del estado sólo es considerado la primera vez que el componente se ejecuta.

import { useState } from "react";

const App = () => {
  const [estado, setEstado] = useState("Estado inicial");

  const receptorEvento = (event) => {
    setEstado(event.target.value);
  };

  return (
    <div>
      <form>
        <div>
          <label>Titulo</label>
          <input type="text" onChange={receptorEvento} />
        </div>
        <button type="submit">Add</button>
      </form>
      <span>{estado}</span>
    </div>
  );
};

export default App;

Conclusión

Podemos conseguir la reactividad comprendiendo la relación entre evento, función receptora de evento y estado. Básicamente seguimos estos pasos:

  1. Añadimos un atributo receptor de evento (onClick, Onchange…) al elemento JSX sobre el cual queremos que se dispare dicho evento.

  2. Le asociamos una función manejadora de eventos, que se ejecutará cada vez que el evento se dispare y que recibirá de manera automática el objeto DOM del elemento sobre el cual se ejecutó el evento.

  3. Dentro de la función manejadora podemos alterar la variable de estado usando la función de estado y, al recibir el objeto de evento, podemos acceder a sus atributos. El más usado es el atributo target.value.