Redux-Toolkit Thunk中无法用useNavigate,登录后如何跳转页面?
Redux action creator属于组件外部代码,确实不能直接调用useNavigate钩子。下面提供三种可行的解决思路:
方案1:组件内监听登录状态完成跳转
利用useSelector监听Redux中登录状态的变化,当状态变为已登录时执行跳转,这是最符合React和Redux设计理念的做法。
首先更新你的authSlice,添加登录状态标识:
import { createSlice } from '@reduxjs/toolkit'; const authSlice = createSlice({ name: 'auth', initialState: { useremail: '', isLoggedIn: false }, reducers: { loginUser: (state, action) => { state.useremail = action.payload.useremail; state.isLoggedIn = true; } } }); export const { loginUser } = authSlice.actions; export default authSlice.reducer;
然后在调用LogUserIn的组件中,监听状态变化并跳转:
import { useSelector, useDispatch } from 'react-redux'; import { useNavigate, useEffect } from 'react-router-dom'; // 组件内部代码 const dispatch = useDispatch(); const navigate = useNavigate(); const { isLoggedIn } = useSelector(state => state.auth); // 监听登录状态,登录成功后跳转 useEffect(() => { if (isLoggedIn) { navigate('/dashboard'); // 替换为你的目标路径 } }, [isLoggedIn, navigate]); const submitInfo = () => { dispatch(LogUserIn(statedata.email, statedata.password, "signUp")); };
方案2:将navigate函数作为参数传入action creator
直接把组件内的navigate函数传给action creator,让它在登录成功后执行跳转。
修改你的LogUserIn action:
export const LogUserIn = (email, password, dir, navigate) => { return async (dispatch) => { try { const response = await fetch(`http://localhost:3000/${dir}`, { method: "post", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }), }); const data = await response.json(); console.log(data); dispatch(authSlice.actions.loginUser({ payload: { useremail: email } })); // 执行跳转 navigate('/dashboard'); } catch (e) { console.log(e); } }; };
组件内调用时传入navigate:
const submitInfo = () => { dispatch(LogUserIn(statedata.email, statedata.password, "signUp", navigate)); };
方案3:让action返回Promise,组件内await后跳转
修改action creator使其返回Promise,在组件内等待dispatch完成后执行跳转,适合需要在跳转前处理额外逻辑的场景。
更新LogUserIn action:
export const LogUserIn = (email, password, dir) => { return async (dispatch) => { try { const response = await fetch(`http://localhost:3000/${dir}`, { method: "post", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }), }); const data = await response.json(); console.log(data); dispatch(authSlice.actions.loginUser({ payload: { useremail: email } })); return Promise.resolve(data); // 返回接口数据供组件使用 } catch (e) { console.log(e); return Promise.reject(e); } }; };
组件内调用并处理跳转:
const submitInfo = async () => { try { // 使用unwrap()获取action的返回值或捕获错误 const loginData = await dispatch(LogUserIn(statedata.email, statedata.password, "signUp")).unwrap(); navigate('/dashboard'); // 可根据loginData做额外处理 } catch (err) { console.error('登录失败:', err); // 登录失败的提示逻辑 } };
内容的提问来源于stack exchange,提问作者Nouman Khan
相关产品推荐
相关产品推荐

