Estoy tratando de establecer una variable dentro de un evento onClick. Estoy configurando los mensajes de error en la variable.
const handleEdit = (e) => { e.preventDefault(); if (edit_user.email == "") { setEditUserError({ email: "Please enter an email!" }) } if (edit_user.company == "") { setEditUserError({ ...edit_user_error, company: "Please enter company!" }) } Y estoy mostrando el error en el formulario como <span className="text-danger">{edit_user_error.company}</span>
El problema es que cuando todos los campos están vacíos y cuando hago clic en el botón, solo se muestra el último mensaje. Cuando dejo un campo vacío y luego hago clic en el botón Enviar, funciona correctamente. Intenté console.log(edit_user_error) pero se muestra vacío. ¿Qué estoy haciendo mal? Por favor ayuda
Esto se debe a las actualizaciones de estado por lotes. React intentará reducir los renderizados minimizando las actualizaciones de estado. Puede usar la actualización del estado funcional para solucionar esto:
if (edit_user.email == "") { setEditUserError({ email: "Please enter an email!" }); } if (edit_user.company == "") { // this callback gets executed only when previous state updates are done setEditUserError((prev) => ({ ...prev, company: "Please enter company!" })); }Para borrar los errores cuando los campos son válidos:
const getErrors = () => { return { ...(!edit_user.email ? { email: "Please enter an email!" } : {}), ...(!edit_user.company ? { company: "Please enter company!" } : {}), }; }; const handleEdit = (e) => { e.preventDefault(); setEditUserError(getErrors()); };Las actualizaciones de estado de reacción son asíncronas, lo que significa que no se ejecutarán de inmediato. Por lo tanto, al ejecutar varios setState en el mismo estado, no puede esperar que el estado de la primera llamada a setState se actualice antes de que ocurra la segunda llamada a setState .
En resumen, React está ignorando sus llamadas anteriores a setState porque suceden una tras otra.
La solución es poner la actualización en una sola llamada:
const handleEdit = (e) => { e.preventDefault(); let errors = {}; if (edit_user.email == "") { errors.email = "Please enter an email!" } if (edit_user.company == "") { errors.company = "Please enter company!" } // and then we call state with all the values, only once setEditUserError(errors);