React Redux登录设置userId后,Booking页面获取值为null的问题
React Redux登录后Booking页面获取userId为null的解决方案
核心问题:页面刷新导致Redux状态丢失
你在登录后使用window.location.href = '/'跳转,这会触发整页刷新。而Redux的状态默认存储在内存中,页面刷新后所有状态都会重置为初始值(也就是userId: null),所以Booking页面拿到的是初始状态。
解决方案1:使用Next.js客户端路由跳转(优先推荐)
替换window.location.href为Next.js的useRouter进行客户端跳转,这种方式不会刷新页面,Redux状态会完整保留:
修改login.js中的handleLogin函数:
import { useRouter } from 'next/router'; // 新增导入 const handleLogin = async (event) => { event.preventDefault(); try { if (!username || !password) { alert('Please enter username and password'); return; } const response = await login(username, password); const data = await response.json(); dispatch(setUserId(data.userId)); // 替换window.location.href为router.push const router = useRouter(); router.push('/'); } catch (error) { console.error('Login failed:', error); // 处理登录失败逻辑(比如显示错误提示) } };
解决方案2:持久化Redux状态(应对页面刷新场景)
如果业务需要允许用户刷新页面后仍保留登录状态,需要把auth状态持久化到localStorage,并在store初始化时读取:
步骤1:修改authSlice,添加持久化逻辑
import { createSlice } from '@reduxjs/toolkit'; // 从localStorage读取已保存的登录状态 const loadAuthState = () => { try { const serializedState = localStorage.getItem('authState'); return serializedState ? JSON.parse(serializedState) : undefined; } catch (err) { console.error('加载登录状态失败:', err); return undefined; } }; // 优先使用localStorage中的状态,没有则用初始值 const initialState = loadAuthState() || { userId: null, isAuthenticated: false, }; const authSlice = createSlice({ name: 'auth', initialState, reducers: { setUserId(state, action) { state.userId = action.payload; state.isAuthenticated = true; // 更新localStorage中的状态 localStorage.setItem('authState', JSON.stringify(state)); }, logout(state) { state.userId = null; state.isAuthenticated = false; // 清除localStorage中的登录状态 localStorage.removeItem('authState'); }, }, }); export const { setUserId, logout } = authSlice.actions; export const selectUserId = (state) => state.auth.userId; export default authSlice.reducer;
步骤2:确认store配置正确
检查你的store配置文件(比如store.js),确保已经正确注册auth reducer:
import { configureStore } from '@reduxjs/toolkit'; import authReducer from './slices/authSlice'; import slotsReducer from './slices/slotsSlice'; // 你的slots reducer export const store = configureStore({ reducer: { auth: authReducer, slots: slotsReducer, }, });
额外检查点
- 验证登录接口返回的
data.userId确实有值,可以在dispatch(setUserId)前添加console.log(data.userId)确认。 - 确认Booking页面的
useSelector路径正确:state.auth.userId,和store中reducer的key保持一致(当前代码中没问题)。
内容的提问来源于stack exchange,提问作者Mahammed Sarfaraz Nawaz Pagala
相关产品推荐
相关产品推荐

