Curso react nivel medio

Introducción
El manejo de formularios es una parte esencial en el desarrollo de aplicaciones web. En React, trabajamos con formularios de una manera declarativa, donde cada cambio en los campos de entrada (inputs) actualiza el estado del componente. Esto permite que el formulario esté siempre sincronizado con el estado.


Formulario Básico: Manejo de Estado con useState

Ejemplo

1import React, { useState } from "react";
2
3function FormularioBasico() {
4  const [nombre, setNombre] = useState("");
5
6  const manejarCambio = (e) => {
7    setNombre(e.target.value);
8  };
9
10  const manejarEnvio = (e) => {
11    e.preventDefault();
12    alert(`El nombre enviado es: ${nombre}`);
13  };
14
15  return (
16    <form onSubmit={manejarEnvio}>
17      <label>
18        Nombre:
19        <input type="text" value={nombre} onChange={manejarCambio} />
20      </label>
21      <button type="submit">Enviar</button>
22    </form>
23  );
24}
25
26export default FormularioBasico;

Explicación

  1. Estado: Usamos useState para guardar el valor del campo nombre.
  2. Control del Input: El valor del input (value) está ligado al estado.
  3. Manejo del Cambio: La función manejarCambio actualiza el estado con el nuevo valor del input.
  4. Manejo del Envío: La función manejarEnvio evita el comportamiento por defecto del formulario y muestra el valor actual en una alerta.

Múltiples Campos con un Solo Estado

Para formularios con varios campos, podemos usar un solo estado para almacenar todos los valores.

Ejemplo

1import React, { useState } from "react";
2
3function FormularioMultiple() {
4  const [formulario, setFormulario] = useState({
5    nombre: "",
6    correo: "",
7  });
8
9  const manejarCambio = (e) => {
10    const { name, value } = e.target;
11    setFormulario({
12      ...formulario,
13      [name]: value,
14    });
15  };
16
17  const manejarEnvio = (e) => {
18    e.preventDefault();
19    alert(`Datos enviados:\nNombre: ${formulario.nombre}\nCorreo: ${formulario.correo}`);
20  };
21
22  return (
23    <form onSubmit={manejarEnvio}>
24      <label>
25        Nombre:
26        <input type="text" name="nombre" value={formulario.nombre} onChange={manejarCambio} />
27      </label>
28      <label>
29        Correo:
30        <input type="email" name="correo" value={formulario.correo} onChange={manejarCambio} />
31      </label>
32      <button type="submit">Enviar</button>
33    </form>
34  );
35}
36
37export default FormularioMultiple;

Explicación

  1. Estado del Formulario: Usamos un objeto para almacenar los valores de cada campo.
  2. name en Inputs: Los inputs tienen un atributo name que indica qué campo están actualizando.
  3. Manejo del Cambio: La función manejarCambio actualiza el campo correspondiente en el estado.

Validación de Formularios

Podemos agregar validaciones para asegurarnos de que los datos ingresados sean correctos.

Ejemplo

1import React, { useState } from "react";
2
3function FormularioValidacion() {
4  const [formulario, setFormulario] = useState({
5    nombre: "",
6    correo: "",
7  });
8  const [error, setError] = useState("");
9
10  const manejarCambio = (e) => {
11    const { name, value } = e.target;
12    setFormulario({
13      ...formulario,
14      [name]: value,
15    });
16    setError(""); // Limpiar errores al escribir
17  };
18
19  const manejarEnvio = (e) => {
20    e.preventDefault();
21    if (!formulario.nombre || !formulario.correo) {
22      setError("Todos los campos son obligatorios");
23      return;
24    }
25    if (!formulario.correo.includes("@")) {
26      setError("El correo debe ser válido");
27      return;
28    }
29    alert("Formulario enviado correctamente");
30  };
31
32  return (
33    <form onSubmit={manejarEnvio}>
34      <label>
35        Nombre:
36        <input type="text" name="nombre" value={formulario.nombre} onChange={manejarCambio} />
37      </label>
38      <label>
39        Correo:
40        <input type="email" name="correo" value={formulario.correo} onChange={manejarCambio} />
41      </label>
42      {error && <p style={{ color: "red" }}>{error}</p>}
43      <button type="submit">Enviar</button>
44    </form>
45  );
46}
47
48export default FormularioValidacion;

Explicación

  1. Estado de Errores: Creamos un estado separado para manejar mensajes de error.
  2. Validación en el Envío: Verificamos que los campos estén llenos y que el correo tenga un formato válido.
  3. Mensajes de Error: Mostramos un mensaje de error si la validación falla.

Usar un Custom Hook para Formularios

Podemos encapsular la lógica de los formularios en un Custom Hook.

Hook useForm

1import { useState } from "react";
2
3function useForm(initialValues) {
4  const [values, setValues] = useState(initialValues);
5
6  const handleChange = (e) => {
7    const { name, value } = e.target;
8    setValues({ ...values, [name]: value });
9  };
10
11  const reset = () => setValues(initialValues);
12
13  return { values, handleChange, reset };
14}
15
16export default useForm;

Usando el Hook

1import React from "react";
2import useForm from "./useForm";
3
4function FormularioConCustomHook() {
5  const { values, handleChange, reset } = useForm({
6    nombre: "",
7    correo: "",
8  });
9
10  const manejarEnvio = (e) => {
11    e.preventDefault();
12    alert(`Nombre: ${values.nombre}\nCorreo: ${values.correo}`);
13    reset();
14  };
15
16  return (
17    <form onSubmit={manejarEnvio}>
18      <label>
19        Nombre:
20        <input type="text" name="nombre" value={values.nombre} onChange={handleChange} />
21      </label>
22      <label>
23        Correo:
24        <input type="email" name="correo" value={values.correo} onChange={handleChange} />
25      </label>
26      <button type="submit">Enviar</button>
27    </form>
28  );
29}
30
31export default FormularioConCustomHook;

Ventajas del Custom Hook

  • Reutilización de Lógica: Puedes usar useForm en cualquier formulario.
  • Código Limpio: Los componentes no necesitan manejar directamente el estado o las funciones de cambio.

Formularios Complejos con Campos Dinámicos

Si necesitas agregar campos dinámicamente, React facilita este proceso.

Ejemplo

1import React, { useState } from "react";
2
3function FormularioDinamico() {
4  const [campos, setCampos] = useState([""]);
5
6  const agregarCampo = () => {
7    setCampos([...campos, ""]);
8  };
9
10  const manejarCambio = (e, index) => {
11    const nuevosCampos = [...campos];
12    nuevosCampos[index] = e.target.value;
13    setCampos(nuevosCampos);
14  };
15
16  const manejarEnvio = (e) => {
17    e.preventDefault();
18    alert(`Valores: ${campos.join(", ")}`);
19  };
20
21  return (
22    <form onSubmit={manejarEnvio}>
23      {campos.map((campo, index) => (
24        <div key={index}>
25          <input
26            type="text"
27            value={campo}
28            onChange={(e) => manejarCambio(e, index)}
29          />
30        </div>
31      ))}
32      <button type="button" onClick={agregarCampo}>
33        Agregar Campo
34      </button>
35      <button type="submit">Enviar</button>
36    </form>
37  );
38}
39
40export default FormularioDinamico;

Explicación

  1. Estado como Array: Usamos un array para almacenar los valores de cada campo.
  2. Agregar Campos: Agregamos un nuevo campo al array cuando el usuario hace clic en "Agregar Campo".
  3. Sincronización de Valores: Cada campo actualiza su posición en el array.

Conclusión

El manejo de formularios en React puede ir desde casos simples hasta casos complejos con validaciones, campos dinámicos y lógica reutilizable. Con herramientas como useState y Custom Hooks, puedes mantener tu código limpio y organizado.