7.2-0-4-Reutilizando el evento onChange

 Optimizando Formularios en React: Reutilizando el evento onChange

En React, los formularios controlados son una parte esencial de muchas aplicaciones. Sin embargo, cuando tenemos múltiples campos, puede resultar tedioso escribir un manejador onChange para cada uno. En este post, te mostraré cómo optimizar tu código reutilizando una sola función onChange para todos los campos del formulario.

El problema inicial

Comencemos con un formulario típico con múltiples campos:

import { useState } from "react";

const MiFormulario = () => {
  const [titulo, setTitulo] = useState("Ejemplo"); // Estado solo para el título

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log({ title: titulo }); // Muestra el título al enviar
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={titulo}
        onChange={(e) => setTitulo(e.target.value)} // Actualiza el título
      />
      <button type="submit">Enviar</button>
    </form>
  );
};

export default MiFormulario;

jsx
import { useState } from "react";

const MiFormulario = () => {
  const [formData, setFormData] = useState({
    title: 'Ejemplo',
    state: 'pendiente'
  });

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(formData);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        placeholder="Título"
        name="title"
        value={formData.title}
        onChange={(e) => setFormData({ ...formData, title: e.target.value })}
      />
      
      <button type="submit">Enviar</button>
    </form>
  );
};

export default MiFormulario;

jsx
Copy
Download
import { useState } from "react"

const MiFormulario = () => {
  const [formData, setFormData] = useState({
    title: 'Ejemplo',
    description: '',
    state: 'pendiente'
  })

  const handleSubmit = (e) => {
    e.preventDefault()
    console.log(formData)
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        placeholder="Título"
        name="title"
        value={formData.title}
        onChange={(e) => setFormData({...formData, title: e.target.value})}
      />
      
      <textarea
        placeholder="Descripción"
        name="description"
        value={formData.description}
        onChange={(e) => setFormData({...formData, description: e.target.value})}
      />
      
      <button type="submit">Enviar</button>
    </form>
  )
}

Como puedes ver, estamos repitiendo la misma lógica en cada manejador onChange, solo cambiando la propiedad que actualizamos.

La solución: Un manejador onChange genérico

Podemos optimizar esto creando una única función handleChange que se encargue de actualizar cualquier campo del formulario:

jsx
Copy
Download
import { useState } from "react"

const MiFormulario = () => {
  const [formData, setFormData] = useState({
    title: 'Ejemplo',
    description: '',
    state: 'pendiente'
  })

  const handleSubmit = (e) => {
    e.preventDefault()
    console.log(formData)
  }

  const handleChange = (e) => {
    const { name, value } = e.target
    setFormData({
      ...formData,
      [name]: value
    })
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        placeholder="Título"
        name="title"
        value={formData.title}
        onChange={handleChange}
      />
      
      <textarea
        placeholder="Descripción"
        name="description"
        value={formData.description}
        onChange={handleChange}
      />
      
      <button type="submit">Enviar</button>
    </form>
  )
}

¿Cómo funciona?

  1. Atributo name: Cada campo del formulario debe tener un atributo name que coincida con la propiedad en nuestro estado.

  2. Destructuración: Extraemos name y value del evento para mayor claridad.

  3. Actualización dinámica: Usamos la sintaxis de propiedades computadas ([name]: value) para actualizar dinámicamente la propiedad correcta en el estado.

Beneficios

  1. Código más limpio: Eliminamos la repetición de lógica similar en múltiples manejadores.

  2. Mantenimiento más fácil: Si necesitamos cambiar la lógica de actualización, solo tenemos que hacerlo en un lugar.

  3. Escalabilidad: Añadir nuevos campos al formulario es tan simple como añadir el elemento con el atributo name correcto.

Conclusión

Reutilizar el manejador onChange es una técnica poderosa que simplifica significativamente el manejo de formularios en React. No solo hace tu código más limpio y mantenible, sino que también reduce la posibilidad de errores al eliminar la repetición de lógica similar.

¿Has utilizado esta técnica en tus proyectos? ¿Tienes alguna variación interesante? ¡Compártelo en los comentarios!

Comentarios

Entradas más populares de este blog

6.5-4-Qué son las Props

6.8-23-pasando funciones a nuestro componente

6.12-0-3- Spread Operator