用户在受限路线中登录后,如何/WAIT A SECOND/导航



所以我的意思是,我有一个功能,在用户登录后,在一秒钟内将他/她导航到主页,例如:

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!');
}
};

但是,我建立了一条受保护的路线,例如:

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;

因此,这里的问题是,每当用户登录或注销时,onAuthStateChanged都会被执行,因此它强制应用程序重新渲染,以了解谁登录和注销了,然后采取相应的行为,比如限制某些路由并允许其他路由。

当用户登录时,我想显示一些toast消息,但它会触发应用程序级别的状态,在我显示toast并导航用户之前,由于限制,它会自动将用户导航到主页,我怎么能等一秒钟再做呢?

您不能在调用setUser()之前等待x段时间吗?这是因为setUser()更新了触发导航的user值。

useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
setIsLoading(true);
setTimeout(() => {
if (user) {
setUser(user);
} else {
setUser(null);
}
setIsLoading(false);
}, 1000);
});
return unsubscribe;
}, []);

或者,将async/await与自定义wait异步函数一起使用,以避免嵌套:

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;
}, []);

允许SignIn组件自己处理重定向。你有两个不同的逻辑,它们正在重定向到"/">

取而代之的是:

<Route
path='/sign-in'
element={!user ? <SignIn /> : <Navigate to='/' />}
/>

切换到此:

<Route
path='/sign-in'
element={<SignIn />}
/>

如果这会导致问题(即,如果您想绕过SignIn,并在用户已经登录的情况下直接转到/(,则应向SignIn添加useEffect调用,并在必要时在那里调用navigate('/');

最新更新