DEV Community

Silviu Technology
Silviu Technology

Posted on

React: errores inline sin mover el formulario

Hay formularios que funcionan, pero se sienten cansados. Escribes tu email, React valida contra la API, aparece un error, luego desaparece, luego el botón baja unos píxeles y el foco queda en un sitio medio raro. No parece grave, pero en flujos de registro o verificación esa micro inestabilidad pega mucho en la confianza.

Lo noto bastante en equipos que hacen checks asíncronos de email: disponibilidad de cuenta, dominios bloqueados, links mágicos o verificación de alta. Cuando QA repite escenarios con un generador de correos falsos o necesita crear correo temporal para aislar pruebas, el formulario deberia ayudar a leer el estado, no meter mas ruido. Ese detalle a veces se deja para el final, y luego cuesta mas arreglarlo de lo que parecia.

Por que los errores inline rompen la calma del formulario

El fallo típico no está en la lógica. Está en cómo entra y sale el mensaje. Un texto corto de ayuda ocupa una línea; un error del backend ocupa tres; el spinner aparece entre ambos. Resultado: el layout cambia varias veces justo cuando la persona intenta decidir qué hacer.

Eso también afecta accesibilidad. web.dev explica que el Cumulative Layout Shift mide cambios inesperados en la página que alteran la experiencia visual, y no hace falta un dashboard gigante para sentirlo: basta con un botón que se mueve mientras ibas a tocarlo. En móvil se nota un monton, y en desktop da esa sensación de producto apurado.

Si además el mensaje llega después de una validación remota, el lector de pantalla puede anunciar contenido nuevo mientras el orden visual ya cambió. No siempre rompe todo, pero sí vuelve la interfaz menos predecible. Y predecible, en temas de Accesibilidad, casi siempre gana.

Que revisar antes de tocar React o CSS

Antes de refactorizar componentes, reviso cuatro cosas:

  • Si el contenedor del mensaje tiene altura estable entre idle, loading y error.
  • Si el CTA principal conserva posición aproximada.
  • Si el foco vuelve a un punto útil cuando cambia el estado.
  • Si el copy de error cabe en la caja prevista sin empujar media pantalla.

Parece básico, pero muchas veces no lo hacemos. Medimos la API, medimos render, y casi nunca medimos quietud visual. Nielsen Norman Group lleva tiempo señalando que los cambios de interfaz durante tareas sensibles elevan la carga cognitiva, y en formularios eso es bastante evidente.

También separo la prueba de email de la prueba visual. Si tu equipo ya tiene una forma de revisar emails de activacion sin mezclar pruebas, úsala para confirmar entrega. Luego evalúa la UI por su cuenta. Esa división hace que los bugs sean mas faciles de nombrar: una cosa es "el correo no llegó" y otra muy distinta es "el formulario se movió feo".

En notas internas siempre aparece algun tempail mail escrito con prisa. No pasa nada. Lo importante es que los estados del producto tengan nombre y espacio fijo, no que la prueba dependa de texto improvisado.

Un patron simple para mensajes estables y foco correcto

Lo que mejor me ha salido en producción es bastante sobrio: reservar espacio para el mensaje desde el primer render y mantener el mismo nodo para ayuda, error y éxito breve. Sin montar tres bloques distintos, sin desmontar el árbol cada vez.

type Status = "idle" | "checking" | "error" | "ok";

const copy: Record<Status, string> = {
  idle: "Usa un email valido para continuar",
  checking: "Comprobando direccion...",
  error: "No pudimos validar este email todavia",
  ok: "Email listo para seguir"
};

export function EmailFieldStatus({ status }: { status: Status }) {
  return (
    <div className="field-status" aria-live="polite">
      <p id="email-status">{copy[status]}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
.field-status {
  min-block-size: 3.5rem;
  display: flex;
  align-items: start;
}
Enter fullscreen mode Exit fullscreen mode

La gracia no está en el snippet. Está en la disciplina alrededor: una caja reservada, un texto breve y un orden que no cambia a cada respuesta. Si luego quieres más detalle, lo pones debajo como ayuda secundaria o dentro de un resumen expandible. El mensaje principal se queda quieto.

En React también intento que la validación asíncrona no dispare estados contradictorios. Si una respuesta vieja llega tarde, prefiero ignorarla antes que reescribir el mensaje correcto con uno viejo. Ese tipo de carrera hace que el formulario parezca buggy aunque técnicamente "todo respondio". Es un error chiquito, pero muy visible.

Como encaja esto con pruebas reales de email

En productos con onboarding, login por enlace o verificación de cuenta, yo pruebo este flujo completo:

  1. Escribir un email nuevo y esperar la validación remota.
  2. Confirmar que el área de mensaje no empuja el botón principal.
  3. Abrir el correo de prueba y volver al formulario o a la pantalla de confirmación.
  4. Verificar que el foco y la jerarquía siguen teniendo sentido.

Para esta parte viene bien un servicio de correo temporal para pruebas, sobre todo si quieres repetir escenarios sin contaminar bandejas reales. Lo importante igual no es la herramienta en si, sino poder observar la transición completa del usuario con menos ruido operativo. Si además ya acostumbras a probar emails de onboarding con menos ruido, mejor todavia.

Hay una idea que me sirve mucho: si el mensaje cambia, el layout no deberia reaccionar como si fuera una sorpresa. El sistema ya sabe que puede haber ayuda, error o confirmación. Entonces reserva ese espacio desde antes. No es la solución más vistosa del mundo, pero sí una de las que mas retorno da por linea de CSS.

Preguntas frecuentes

¿Reservar espacio no deja huecos innecesarios?

Un poco, sí. Pero prefiero un hueco controlado a un formulario inquieto. Con buen espaciado casi ni se nota, y la percepción general mejora bastante.

¿Esto ayuda aunque el problema real esté en backend?

Sí, porque separa capas. Si la API tarda, al menos la UI sigue siendo clara y estable. Esa claridad compra paciencia, y eso vale mucho.

¿Hace falta hacerlo en formularios pequeños?

También. De hecho, en pantallas cortas se nota más. Un cambio de 20 o 30 píxeles puede parecer minimo en Figma, pero en uso real se siente bastante.

Top comments (0)