En React, estoy usando la context API
para configurar los datos del usuario o los errores devueltos por la solicitud de la API:
// context const [currentUser, setCurrentUser] = useState("") const [error, setError] = useState("") async function login(credentials) { setError("") try { ...API request const data = await response.json() if(data.success) { setCurrentUser(data) } else { setError(data.error) } } catch (error) { setError("Something went wrong. Please try again.") } } <AuthContext.Provider value={login, currentUser, error}> {children} </AuthContext.Provider>
Luego en mi componente:
//component const { login, currentUser, error } = useContext(AuthContext) const onSubmit = async (credentials) => { setLoading(true) await login(credentials) resetForm({}) setLoading(false) !error && navigate("/") } return ( ... )
Ahora, la función onSubmit
le permite al usuario navigate
a /
incluso si hay un error
establecido por el context
; esto se debe a que (creo) el error
aún es null
cuando se verifica y el componente no tiene la oportunidad de volver a procesar para obtener el valor más reciente.
¿Cuál sería el mejor enfoque para evitar este comportamiento? ¿Debo manejar el error localmente en el componente y no en el context
? En caso afirmativo, ¿cuál sería la mejor manera de hacerlo en mi escenario?
¡Gracias!
Por supuesto, hay otras formas de hacer esto, pero la que no cambiaría mucho su estructura actual es cambiar la función onSubmit
para que no haga la redirección allí:
const onSubmit = async (credentials) => { setLoading(true) await login(credentials) resetForm({}) setLoading(false) }
Cree un useEffect
que haría la redirección, pero en función de si hay un usuario o no:
useEffect(()=>{ if(currentUser){ navigate("/") } },[currentUser])
Y sí, cuando está llamando a !error && navigate("/")
todavía no se ha vuelto a procesar y, por lo tanto, error
sigue siendo igual a ""
, por lo que la redirección se produce de inmediato.
Suponiendo que el proceso de inicio de sesión se maneje en un solo lugar (que es el caso en la mayoría de los escenarios), no es necesario tener la función de inicio de login
y el estado de error
como parte del contexto. El contexto debe exportar solo setCurrentUser
y currentUser
.
<AuthContext.Provider value={currentUser, setCurrentUser}> {children} </AuthContext.Provider>
El inicio de sesión y los errores relacionados con el inicio de sesión se manejarían dentro de la página de inicio de sesión y llamaría a setCurrentUser
para actualizar el contexto de otros componentes:
const {currentUser, setCurrentUser} = useContext(AuthContext)
Y usaría el mismo useEffect
que el anterior para hacer la redirección cuando hay currentUser
.