React Firebase v9项目侧边栏无法显示用户displayName问题求助
核心问题点
代码里共有4处核心问题直接导致displayName无法正常显示:
- App.js中
onAuthStateChanged回调判断条件写错:判断的是本地state存储的user,而非Firebase回调返回的authUser,状态判断逻辑完全混乱 onAuthStateChanged直接写在组件函数体中,没有用useEffect包裹,每次组件重渲染都会注册新的监听,触发无限重渲染循环,状态更新完全失控- Register.js中调用
updateProfile修改用户资料后,没有重载用户信息,Firebase Auth本地缓存的还是不带displayName的旧用户对象,监听回调拿不到更新后的字段 - 初始user state设为空数组
[],和后续存储的用户对象、未登录状态的空值类型不匹配,容易引发隐式判断错误
具体修复代码
1. 修正App.js逻辑
将auth监听移入useEffect,修正判断条件,统一状态类型,合并冗余路由写法:
import React, {useState, useEffect} from "react"; import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import { getAuth, onAuthStateChanged } from "firebase/auth"; import { app } from "./firebase.js"; import "./App.css"; import LoginHeader from "./LoginHeader.js"; import Login from "./Login.js"; import RegisterHeader from "./RegisterHeader.js"; import Register from "./Register.js"; import HomeHeader from "./HomeHeader.js"; import Sidebar from "./Sidebar.js"; import Post from "./Post.js"; import News from "./News.js"; function App() { // 初始值设为null代表鉴权状态未加载完成,不要用空数组 const [user, setUser] = useState(null); const auth = getAuth(app); // 组件挂载时仅注册一次auth监听,卸载时清理监听防止内存泄漏 useEffect(() => { const unsubscribe = onAuthStateChanged(auth, (authUser) => { // 直接判断回调返回的authUser对象,不要判断本地state的user if(authUser){ setUser(authUser); } else { setUser(null); } }) return () => unsubscribe(); }, [auth]) return ( <Router> <div className="App"> <Routes> <Route path = "/" element = {<LoginHeader />} /> <Route path = "/" element = {<Login />} /> <Route path = "/register" element = {<RegisterHeader />} /> <Route path = "/register" element = {<Register />} /> <Route path = "/home" element = {<HomeHeader />} /> </Routes> <div className = "appBody"> <Routes> <Route path = "/home" element = {<Sidebar user = {user} /> }/> <Route path = "/home" element = {<div className = "homePosts"> <Post /> </div>} /> <Route path = "/home" element = {<News />} /> </Routes> </div> </div> </Router> ); } export default App;
2. 修正Register.js更新逻辑
更新完用户资料后强制重载用户信息,确保缓存同步后再跳转:
const register = () => { console.log(email, password); createUserWithEmailAndPassword(auth, email, password) .then(async (userCredentials) => { const user = userCredentials.user; // 等待资料更新完成 await updateProfile(user, { displayName: userID }) // 关键步骤:重载用户信息,刷新本地auth缓存 await user.reload(); // 所有异步操作完成后直接跳转首页,无需绕道登录页 navigate("/home"); }).catch((error) => { alert(error.message); }) }
3. Sidebar.js小优化
原有可选链写法可正常运行,加个简单加载态避免空白即可:
function Sidebar({user}) { return ( <div className = "sidebar"> <SidebarOption avatar Icon = {SentimentSatisfiedAltIcon} title = {user?.displayName || '加载中...'} /> <SidebarOption Icon = {HomeIcon} text = "Home"/> <SidebarOption Icon = {ProfileIcon} text = "Profile"/> <SidebarOption Icon = {ChatIcon} text = "Chat"/> <SidebarOption Icon = {HelpIcon} text = "Help"/> </div> ); }
修改完成后清空浏览器缓存,重新注册账号或重新登录已有账号,侧边栏即可正常显示displayName字段。
内容的提问来源于stack exchange,提问作者Santi
相关产品推荐
相关产品推荐

