Capturar datos de un formulario de login en React puede hacerse de varias formas, pero combinar useRef con FormData ofrece una solución limpia, segura y directa. Este enfoque evita re-renderizados innecesarios y aprovecha las capacidades nativas de JavaScript para empaquetar la información antes de enviarla al backend.
¿Cómo funciona useRef para referenciar un formulario completo?
El hook useRef permite crear una referencia directa a un elemento del DOM sin provocar nuevos renders cada vez que el usuario escribe. En lugar de crear un useState por cada input o usar onChange para rastrear cambios, se genera una sola referencia al formulario completo [01:40].
El proceso es sencillo:
- Se importa
useRef desde React.
- Se declara una constante, por ejemplo
form, inicializada con useRef(null) porque aún no apunta a ningún elemento.
- En la etiqueta
<form> del JSX se agrega el atributo ref={form}.
Con esto, form.current contiene el nodo del formulario y todos los inputs que viven dentro de él. La propiedad current es la que almacena el valor actual de la referencia en todo momento [02:12].
¿Qué ventajas ofrece FormData frente a otras estrategias?
FormData es una API nativa de JavaScript que instancia todos los campos de un formulario y los captura automáticamente cuando se ejecuta el submit [03:05]. Al pasarle form.current, genera un objeto con cada input identificado por su atributo name.
Esto implica un cambio importante: los inputs ya no se identifican por id, sino por name. Así, formData.get('email') devuelve lo que el usuario escribió en el campo cuyo name es email, y formData.get('password') hace lo propio con la contraseña [04:30].
Las ventajas principales son:
- Seguridad: la información viaja encapsulada, no expuesta directamente en la URL ni en el estado del componente.
- Simplicidad: no se necesitan múltiples estados ni eventos
onChange por cada campo.
- Compatibilidad con el backend: el objeto FormData puede enviarse tal cual en una petición HTTP.
¿Cómo se construye la función handleSubmit?
Dentro del componente se crea una función handleSubmit que ejecuta la lógica al presionar el botón de login [03:30]. Su estructura es directa:
javascript
const handleSubmit = (event) => {
event.preventDefault();
const formData = new FormData(form.current);
const data = {
username: formData.get('email'),
password: formData.get('password'),
};
console.log(data);
};
El botón dispara esta función mediante el evento onClick={handleSubmit}. Se construye un nuevo FormData a partir de la referencia actual del formulario y luego se extraen los valores con el método get [04:50].
¿Por qué es necesario preventDefault?
Cuando un formulario HTML ejecuta un submit, el comportamiento por defecto es recargar la página y enviar los datos como parámetros en la URL. Esto rompe la experiencia en una single page application con React [08:15].
event.preventDefault() intercepta ese comportamiento nativo y permite que la lógica definida en handleSubmit se ejecute sin recargas ni exposición de datos en la barra de direcciones [08:40]. Sin esta línea, los valores aparecerían como query params y la página se refrescaría, perdiendo el estado de la aplicación.
¿Qué consideraciones de estructura hay que tener en JSX?
Durante la transformación de elementos en el JSX, es fundamental cerrar las etiquetas correctamente. Un error frecuente es cerrar un <button> como etiqueta autocerrada y al mismo tiempo agregar una etiqueta de cierre </button>. La regla es clara: o se usa autocerramiento o se abren y cierran con contenido hijo dentro [07:30].
jsx
<button className="login-btn" onClick={handleSubmit}>
Login
</button>
También conviene estructurar los atributos del componente en líneas separadas cuando se acumulan propiedades como className, type y onClick, mejorando la legibilidad del código.
Con useRef apuntando al formulario, FormData extrayendo los valores y preventDefault controlando el flujo, se obtiene un mecanismo robusto para capturar credenciales y prepararlas para la autenticación. ¿Has probado enviar el objeto FormData directamente al backend en lugar de parsearlo? Comparte tu experiencia.