登录后无法重定向至受保护路由 首次提交凭证跳转失效求助
你猜测的原因完全正确,dispatch(login(data))属于异步操作,当前同步执行的写法会导致history.push在token写入localStorage、Redux登录状态更新完成前就触发,此时受保护路由的鉴权逻辑无法检测到有效凭证,因此跳转失败。第二次提交时前一次请求生成的token已经存入localStorage,所以可以正常通过鉴权完成跳转。
解决方案
方案1:异步等待登录Action执行完成(推荐)
前提是你使用了redux-thunk、redux-toolkit等支持异步Action的中间件,先改造login Action,在执行完成后返回Promise:
// 改造你的login thunk Action export const login = (loginData) => async (dispatch) => { const response = await loginApi(loginData) const { token, userInfo } = response.data // 写入localStorage和更新Redux状态 localStorage.setItem('token', token) dispatch({ type: 'USER_LOGIN_SUCCESS', payload: userInfo }) // 抛出执行结果,供外层调用时判断状态 return response }
之后将submitAction改为异步函数,等待login Action执行完成后再触发跳转:
const submitAction = async (data) => { try { // 等待登录、token写入、状态更新全部完成 await dispatch(login(data)) history.push(`${private_component}`) } catch (error) { // 可在此处添加登录失败的提示逻辑 console.log('登录失败:', error) } }
方案2:监听Redux登录状态触发跳转
适用于登录逻辑分散在多处的场景,将跳转逻辑和提交逻辑解耦:
- 首先从Redux中获取登录状态标识
- 用useEffect监听该状态,状态变更为已登录时自动跳转
import { useSelector } from 'react-redux' import { useEffect } from 'react' // 在你的登录组件内添加以下逻辑 const isLogin = useSelector(state => state.user.isLogin) useEffect(() => { if (isLogin) { history.push(`${private_component}`) } }, [isLogin, history])
兜底方案:路由层添加重定向逻辑
可以在登录路由的鉴权逻辑中添加判断,如果用户已持有有效token,直接重定向到受保护页面,避免用户手动访问登录页重复操作:
// 路由配置示例 <Route path="/login" element={ localStorage.getItem('token') ? <Navigate to="/dashboard" replace /> : <LoginPage /> } />
内容的提问来源于stack exchange,提问作者Shane Watson
相关产品推荐
相关产品推荐

