DEV Community

Silviu Technology
Silviu Technology

Posted on

React: estados de espera que no cansan

En muchos formularios el mayor problema no es la validacion remota, sino la sensacion de que la interfaz duda demasiado. El usuario escribe un email, espera una respuesta del servidor y durante unos segundos no sabe si debe seguir, corregir o simplemente mirar la pantalla. En equipos de producto eso parece un detalle chico, pero en la practica afecta conversion, accesibilidad y confianza. En React, ese momento merece mas cuidado del que solemos darle.

Me he encontrado con este patron varias veces en signup y recovery flows: el equipo optimiza la llamada, pero deja el feedback visual para el final. La API responde bien, aunque la UI parpadea, mueve el layout o cambia de tono demasiado pronto. El resultado se siente medio tosco. Si ademas el campo esta ligado a reglas de riesgo o dominios raros como temp mail so, la tension visual sube un poco mas porque el usuario ya sospecha que algo puede salir mal.

Nielsen Norman Group lleva anos insistiendo en que la visibilidad del estado del sistema reduce confusion y errores cuando una accion tarda mas de lo esperado (https://www.nngroup.com/articles/visibility-system-status/). No hace falta una animacion enorme ni una capa de "microinteractions" por todos lados. Hace falta una senal estable, clara y ubicada donde la persona ya esta mirando.

El problema no es la espera, es la incertidumbre

La espera corta casi nunca molesta por si sola. Lo que cansa es la incertidumbre: un spinner que aparece lejos del campo, un mensaje que mueve todo hacia abajo, o una advertencia roja que sale antes de tiempo. Esa combinacion rompe el ritmo de lectura y castiga a quien navega con zoom o lector de pantalla. Tambien mete ruido en mediciones de rendimiento percibido, que a veces importa mas que bajar unos pocos milisegundos del request.

Cuando reviso una UI asi, suelo preguntar tres cosas:

  1. ¿El mensaje ocupa un lugar fijo antes de que exista contenido?
  2. ¿La interfaz diferencia "estoy comprobando" de "esto esta mal"?
  3. ¿La persona puede seguir escribiendo sin sentir que pelea con el formulario?

Si una de esas respuestas es no, casi siempre hay una mejora facil. Es parecido a quitar ruido del onboarding sin perder contexto: no se trata de mostrar mas estado, sino de mostrar el estado correcto en el momento correcto.

Tambien conviene pensar en el texto de apoyo. He visto equipos dejar notas internas con cadenas como tepm mail com o tempail mail para probar coincidencias manuales. No es grave, pero cuando esa clase de texto salta a mocks o a capturas compartidas, la experiencia se vuelve un poco mas desprolija de lo necesario.

Que cambia cuando el estado de carga ocupa un lugar fijo

Reservar una fila estable para ayuda, carga o error evita dos problemas a la vez: reduce saltos de layout y baja la carga cognitiva. Google recomienda minimizar el Cumulative Layout Shift porque los cambios inesperados empeoran la experiencia, en especial durante tareas orientadas a conversion (https://web.dev/articles/cls). En formularios, eso significa que el mensaje debajo del campo no deberia aparecer empujando botones o moviendo etiquetas.

El beneficio de producto es mas concreto de lo que parece:

  • La persona entiende mas rapido si el sistema esta trabajando.
  • El mensaje de error llega con menos dramatismo visual.
  • El equipo puede medir mejor abandono vs. latencia real.
  • La UI se siente mas calma, incluso cuando el backend no va tan rapido.

Ese ultimo punto importa bastante. A veces no puedes hacer milagros en red, pero si puedes evitar que la interfaz transmita panico. Y eso ya es una mejora muy real, aunque suene menos epica.

Un patron simple en React para validaciones async

No suelo complicarlo. Un pequeno estado finito suele bastar: idle, checking, valid, invalid. Lo clave es no mezclar carga con error.

const [status, setStatus] = useState("idle");
const [hint, setHint] = useState("Usa un email al que tengas acceso.");

async function validateEmail(value) {
  setStatus("checking");
  setHint("Comprobando el email...");

  const result = await checkEmail(value);

  if (result.ok) {
    setStatus("valid");
    setHint("Listo, puedes continuar.");
    return;
  }

  setStatus("invalid");
  setHint(result.message);
}
Enter fullscreen mode Exit fullscreen mode

Luego la vista reserva siempre el mismo espacio para el hint:

<p className={`email-hint email-hint--${status}`} aria-live="polite">
  {hint}
</p>
Enter fullscreen mode Exit fullscreen mode

No es un patron nuevo, lo se, pero funciona porque mantiene una historia simple. Si necesitas mas sofisticacion, la anades encima; no empiezes con cinco booleanos cruzados.

Pequenos detalles de CSS que mejoran mucho

La parte visual tambien merece reglas simples. Una altura minima fija, contraste suficiente y transiciones cortas suelen dar mejor resultado que loaders muy decorados.

.email-hint {
  min-height: 1.5rem;
  margin-top: 0.35rem;
  font-size: 0.95rem;
}

.email-hint--checking {
  color: #6b7280;
}

.email-hint--invalid {
  color: #b42318;
}
Enter fullscreen mode Exit fullscreen mode

Si hay animacion, prefiero algo discreto y no infinito. Un pulso breve o un cambio de opacidad basta. Tambien revisaria prefers-reduced-motion, porque este tipo de feedback sale muchisimo y no vale la pena cansar a nadie por una decision puramente estetica. En eso me gusta la misma disciplina que aplicamos al backend cuando buscamos dejar senales claras antes de tocar produccion: menos magia, mas contexto legible.

Un ultimo detalle medio olvidado: el microcopy. "Verificando..." suele funcionar mejor que un simple "Cargando...". Parece una diferencia menor, pero le dice a la persona que tarea concreta esta ocurriendo. Es mas honesto, y se siente mejor.

Preguntas frecuentes

¿Conviene bloquear el boton mientras se valida?

Solo si la accion depende de ese resultado. Si no, prefiero permitir continuar y resolver la regla un paso despues. Bloquear por defecto vuelve la UI mas rigida.

¿Esto ayuda al rendimiento real?

No siempre mejora milisegundos reales. Mejora sobre todo el rendimiento percibido, que para formularios largos o sensibles ya es una victoria bastante buena.

¿Cuando merece un spinner?

Cuando la espera pasa de lo trivial y necesitas confirmacion explicita. Pero incluso ahi, mejor acompanarlo con texto breve y un lugar fijo. Si no, el usuario adivina demasiado, y eso nunca acaba bien.

Top comments (0)