MERN栈Google OAuth登录后导航栏无需刷新显示用户信息问题
解决Google OAuth登录后导航栏即时显示用户信息的问题
用户通过Google OAuth登录后会被重定向至首页,用户数据已存储到localStorage中,但导航栏的用户名和头像只有刷新页面后才会显示,需要实现登录跳转后即时展示的功能。
问题原因
原Navbar组件通过useState从localStorage初始化用户数据,但没有监听Redux状态或localStorage的变化,导致登录后数据更新时组件不会自动重新渲染。
解决方案
1. 修改Navbar组件,直接从Redux获取状态
改用Redux的useSelector订阅全局状态,当登录时Redux状态更新,Navbar会自动重新渲染。
修改后的navbar.js:
import { AppBar, Typography, Toolbar, Avatar, Button, Container } from "@mui/material"; import React from "react"; import { Link } from 'react-router-dom' import useStyles from './styles' import memories from '../../images/memories.png' import { useDispatch, useSelector } from "react-redux"; import { useNavigate } from "react-router-dom"; import { logoutAuth } from "../../reducers/auth"; const Navbar = () => { const classes = useStyles() const dispatch = useDispatch() const navigate = useNavigate() // 直接从Redux store获取最新用户数据 const user = useSelector(state => state.auth.authData) const logout = () => { dispatch(logoutAuth()) navigate('/auth') } return ( <> <AppBar className={classes.appBar} position='static' color='inherit'> <Container maxWidth="xl" style={{ display: 'flex', flexDirection: 'row' }}> <div className={classes.brandContainer}> <img className={classes.image} src={memories} alt="memories" height="50" /> <Typography variant='h4' nowrap className={classes.heading} >Travel Blog</Typography> </div> <Toolbar className={classes.toolbar} style={{ marginLeft: 'auto' }}> {user ? ( <div className={classes.profile}> <Avatar className={classes.purple} alt={user.name} src={user.picture}>{user.name.charAt(0)}</Avatar> <Typography className={classes.userName} variant='h6'>{user.name}</Typography> <Button variant="contained" className={classes.logout} color="secondary" onClick={logout} >Logout</Button> </div> ) : ( <Button component={Link} to="/auth" variant="contained" color="primary" style={{ marginLeft: 'auto' }}> Sign In </Button> )} </Toolbar> </Container> </AppBar> </> ) } export default Navbar
2. 完善Redux登出逻辑
原logoutAuth只删除了localStorage的数据,没有清空Redux中的状态,需要补充这一步:
修改后的reducers_auth.js:
import { createSlice } from "@reduxjs/toolkit"; import { jwtDecode } from "jwt-decode"; const initialState = { authData: null, }; const authSlice = createSlice({ name: 'auth', initialState, reducers: { setAuthData(state, action) { const user_data = jwtDecode(action.payload); state.authData = user_data; localStorage.setItem('profile', JSON.stringify(user_data)); }, logoutAuth(state) { localStorage.removeItem('profile'); // 清空Redux中的用户数据,确保Navbar能感知到登出状态 state.authData = null; } } }) export const { setAuthData, logoutAuth } = authSlice.actions; export default authSlice.reducer;
3. 保留原登录逻辑
auth.js中的登录逻辑无需修改,因为已经正确dispatchsetAuthData更新了Redux状态和localStorage。
效果验证
登录成功后,setAuthData会更新Redux的auth.authData状态,Navbar通过useSelector获取到最新数据,自动重新渲染并显示用户名和头像,无需刷新页面。
内容的提问来源于stack exchange,提问作者LOKESH R
相关产品推荐
相关产品推荐

