DEV Community

Silviu Technology
Silviu Technology

Posted on

React: verifica emails sin perder contexto

Un formulario de registro puede enviar un email correctamente y aun así ofrecer una experiencia confusa. El usuario pulsa “Verificar”, la interfaz muestra un spinner, llega el mensaje y, de pronto, el foco termina en un lugar inesperado. En móvil esto se nota más; con un lector de pantalla, puede parecer que el botón desapareció.

En este artículo comparto un patrón sencillo de React para que un flujo de verificación tenga estados visibles, anuncios útiles y una recuperación clara cuando algo falla. Es una mejora pequeña, pero suele tener un efecto medible en soporte y en pruebas de accesibilidad.

El problema no es enviar el email

El problema es que la interfaz no explica bien la transición. Un flujo de email tiene, como minimo, estos momentos:

  1. El formulario está listo para enviarse.
  2. La solicitud está pendiente.
  3. El email fue solicitado y el usuario debe revisar su bandeja.
  4. La solicitud falló o el enlace expiró.

Si todos se representan con el mismo botón desactivado, los usuarios no sabe qué pasó. La solución no necesita una librería grande: primero hay que definir un contrato de estados y luego reflejarlo en HTML semántico.

También conviene separar el contenido de prueba del contenido real. Para validar una cuenta en staging, un generador de correo desechable puede aislar mensajes y enlaces sin llenar una bandeja personal. El mismo criterio aparece en un checklist de emails antes de lanzar: probar el mensaje es solo una parte; hay que probar qué entiende la persona.

Un contrato pequeño para los estados

Mantengo el estado explícito y evito que el texto dependa de un spinner. Así el diseño puede cambiar sin romper la lógica:

const [status, setStatus] = useState("idle");

async function requestVerification(email) {
  setStatus("pending");
  try {
    await sendVerificationEmail(email);
    setStatus("sent");
  } catch {
    setStatus("error");
  }
}
Enter fullscreen mode Exit fullscreen mode

La vista puede mostrar una frase diferente para cada estado. En pending, el botón debe comunicar que la acción está en curso, pero no hay que ocultar el label ni sustituirlo por un icono sin nombre. En sent, el mensaje debe decir qué hacer después: revisar la bandeja, mirar spam y volver a esta página si hace falta.

Para el caso error, ofrezco un botón para reintentar y conservo el email escrito. Borrar el formulario después de un fallo es una fricción evitable y una estado vacío no ayuda a nadie.

React y foco estable

Una región aria-live="polite" sirve para anunciar cambios sin interrumpir una lectura activa. No hace falta anunciar cada render: un mensaje corto cuando la solicitud termina suele ser suficiente.

<p aria-live="polite" role="status">
  {status === "pending" && "Enviando el email de verificación…"}
  {status === "sent" && "Email enviado. Revisa tu bandeja y la carpeta de spam."}
  {status === "error" && "No se pudo enviar. Puedes intentarlo de nuevo."}
</p>
Enter fullscreen mode Exit fullscreen mode

Cuando aparece un error de validación, muevo el foco al primer campo con problema. Cuando la solicitud termina bien, prefiero dejar el foco en el botón o llevarlo a un encabezado del mensaje solo si la navegación lo necesita. El foco no debe saltar porque una petición lenta cambió el DOM.

Para flujos con varias pantallas, los correos de cambio con contexto verificable recuerdan una idea útil: cada evento necesita contexto. En la UI, eso significa mantener visible el estado, el destinatario y la acción siguiente.

CSS, rendimiento y movimiento

El estado pendiente no necesita una animación pesada. Un borde o un cambio de color con suficiente contraste puede ser más rápido y más claro que un spinner continuo. Si uso transición, respeto la preferencia del sistema:

.verification-message {
  min-height: 2.5rem;
  contain: content;
}

@media (prefers-reduced-motion: reduce) {
  .verification-spinner {
    animation: none;
  }
}
Enter fullscreen mode Exit fullscreen mode

min-height reduce el salto de layout cuando aparece el mensaje. Es util en formularios pequeños, donde un cambio de dos líneas puede empujar el botón fuera de la zona visible. También reviso contraste, tamaño de toque y el orden de tabulación; una etiqueta bonita no compensa un control dificil de usar.

Las búsquedas reales no siempre vienen bien escritas: alguien puede teclear “tempail mail” o “tamp mail com”. Esos términos sirven como recordatorio de que el lenguaje debe ser tolerante, pero no los usaría como texto principal de una interfaz ni como ancla de enlace.

Qué probar antes de publicar

Mi lista mínima combina teclado, lector de pantalla y una prueba de red lenta:

  • ¿El botón tiene un nombre estable durante toda la solicitud?
  • ¿El mensaje de éxito o error se anuncia una sola vez?
  • ¿El foco sigue en un lugar lógico después de cada transición?
  • ¿El formulario conserva sus datos después de un fallo?
  • ¿La interfaz funciona al ampliar el texto y con movimiento reducido?
  • ¿Una respuesta lenta evita doble envío y mantiene una explicación visible?

También miro un caso que suele olvidarse: el enlace llega tarde, el usuario vuelve a pedirlo y luego abre el primer mensaje. La pantalla debería explicar si los enlaces anteriores siguen válidos o si solo el último funciona. Un use and throw email puede ayudar a aislar el escenario en pruebas, pero el contrato de estados sigue siendo responsabilidad del frontend.

Preguntas rápidas

¿Debo usar aria-live en todo el formulario?

No. Una región pequeña y estable es mas predecible. Anuncia solo cambios que la persona necesita conocer para continuar.

¿Hay que enfocar siempre el mensaje de éxito?

No. Si el mensaje está cerca del control y se anuncia correctamente, conservar el foco suele ser menos disruptivo. En una navegación de página completa sí puede tener sentido enfocarlo.

¿Cómo medir la mejora?

Registra reintentos, abandonos y errores de verificación, pero interprétalos junto con pruebas manuales. Una tasa baja de error técnico no significa que la interfaz sea comprensible; una revisión visual y con teclado ayudan a encontrar lo que las métricas no muestran.

La verificación de email es un flujo pequeño, pero tiene varias transiciones. En React, un contrato de estados claro, foco estable y CSS respetuoso hacen que la UI sea mas rápida de entender, además de más accesible.

Top comments (0)