Tengo un formulario de registro en mi aplicación Next.js.
Comportamiento no deseado: si el usuario hace clic en el botón de envío "registrarse" varias veces seguidas, la aplicación realiza varias solicitudes de búsqueda y se muestran varios avisos en la interfaz.
Comportamiento deseado: el usuario no debería poder realizar ninguna acción después de presionar enviar hasta que se complete el primer envío.
Lo primero que hice fue hacer que la llamada a la API fuera síncrona. Pero por razones que no entiendo completamente, esto parece ser una mala idea:
Miré otras preguntas en líneas similares, pero las respuestas no ayudaron:
No entiendo muy bien por qué una solicitud síncrona no es la mejor práctica aquí. Seguro que estoy bloqueando la CPU durante una operación de E/S, pero no quiero que la página haga nada hasta que se complete el envío del formulario.
¿Cuál es el método recomendado para evitar el rebote del cambio en el envío del formulario y podría explicar por qué?
src/pages/auth/sign-up.js:
const onSubmit = async (data) => { const { email, password1, password2, first_name, last_name } = data; const response = await postSignUp( email, password1, password2, first_name, last_name ); // error handling code toast.success('You have successfully registered!', { autoClose: 2500 }) setTimeout( () => { router.push({ pathname: '/auth/verify-email', query: { email: email } }); }, 2500 )/src/lib/api.js:
export async function postSignUp(email, password1, password2, first_name, last_name) { const response = await fetch(SIGN_UP_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify( { email, password1, password2, first_name, last_name } ), }); const json = await response.json(); return json; }Un método muy simple y generalmente utilizado es hacer que el botón de envío esté deshabilitado hasta que obtenga una respuesta de su API. Así por ejemplo:
Crear un estado:
const [isSubmitting, setIsSubmitting] = useState(false); Use ese estado para configurar el atributo disabled de su botón de envío:
<button type="submit" disabled={isSubmitting}>Save</button> Llame a setIsSubmitting desde su controlador de eventos:
const onSubmit = async (data) => { setIsSubmitting(true); const { email, password1, password2, first_name, last_name } = data; const response = await postSignUp( email, password1, password2, first_name, last_name ); // error handling code toast.success('You have successfully registered!', { autoClose: 2500 }) setTimeout( () => { router.push({ pathname: '/auth/verify-email', query: { email: email } }); }, 2500 ) setIsSubmitting(false); }