Entonces, lo que quiero decir es que tengo una funcionalidad después de que el usuario inicie sesión, navegue a él / ella a la página de inicio en un segundo, como:
const handleSignIn = async (e) => { e.preventDefault(); const user = await signIn(formData); if (user) { toast.success('Signed In!'); setTimeout(() => { navigate('/'); }, 1000); } else { toast.error('Bad user credentials!'); } };Pero, construí una ruta protegida, como:
function App() { const [user, setUser] = useState(null); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const unsubscribe = onAuthStateChanged(auth, (user) => { setIsLoading(true); if (user) { setUser(user); } else { setUser(null); } setIsLoading(false); }); return unsubscribe; }, []); if (isLoading) return <Spinner />; return ( <> <Router> <Routes> <Route path='/' element={<PrivateRoute />}> <Route index element={<Explore />} /> <Route path='/offers' element={<Offers />} /> <Route path='/profile' element={<Profile />} /> <Route path='/contact/:landlordId' element={<Contact />} /> <Route path='/create-listing' element={<CreateListing />} /> <Route path='/category/:categoryName' element={<Category />} /> <Route path='/category/:categoryName/:id' element={<Listing />} /> </Route> <Route path='/sign-in' element={!user ? <SignIn /> : <Navigate to='/' />} /> <Route path='/sign-up' element={!user ? <SignUp /> : <Navigate to='/' />} /> <Route path='/forgot-password' element={!user ? <ForgotPassword /> : <Navigate to='/' />} /> </Routes> {user && <Navbar />} </Router> <ToastContainer autoClose={1000} /> </> ); } export default App;Entonces, el problema aquí es que, cada vez que el usuario inicia sesión o cierra sesión, onAuthStateChanged se ejecuta, por lo tanto, obliga a la aplicación a volver a procesar para comprender quién inició sesión y quién cerró la sesión y luego se comporta en consecuencia, como restringir algunas rutas y permitir otras.
Cuando el usuario inicia sesión, me gustaría mostrar un mensaje de brindis PERO activa el estado de nivel de la aplicación y antes de mostrar el brindis y navegar al usuario, automáticamente lleva al usuario a la página de inicio debido a la restricción, ¿cómo puedo esperar un segundo antes de hacerlo? ¿que?
¿No puedes esperar x cantidad de tiempo antes de llamar a setUser() ? Esto se debe a que setUser() actualiza el valor del user , lo que activa la navegación.
useEffect(() => { const unsubscribe = onAuthStateChanged(auth, (user) => { setIsLoading(true); setTimeout(() => { if (user) { setUser(user); } else { setUser(null); } setIsLoading(false); }, 1000); }); return unsubscribe; }, []); Alternativamente, use async/await con una función de wait asíncrona personalizada que evitará el anidamiento:
const wait = async (d) => new Promise(r => setTimeout(d, r)); useEffect(() => { const unsubscribe = onAuthStateChanged(auth, async (user) => { setIsLoading(true); await wait(1000); if (user) { setUser(user); } else { setUser(null); } setIsLoading(false); }); return unsubscribe; }, []);Permita que el componente SignIn , maneje la redirección por sí mismo. Tienes dos piezas de lógica diferentes que están redirigiendo a "/"
En lugar de esto:
<Route path='/sign-in' element={!user ? <SignIn /> : <Navigate to='/' />} />Cambia a esto:
<Route path='/sign-in' element={<SignIn />} /> Si eso causa un problema (es decir, si desea omitir Iniciar sesión e ir directamente a / si el usuario ya inició sesión), debe agregar una llamada useEffect a Iniciar sesión y llamar a navigate('/'); allí si es necesario.