React.js集成Firebase登录报错:TypeError: setUser is not a function
问题修复方案
核心问题定位
AdminLogin组件在App.js的路由中渲染时,没有传入setUser和setAuthState这两个props,导致组件内部调用setUser(email)时触发TypeError: setUser is not a function。
另外还有两个次要问题:
- App.js中
useEffect的依赖数组包含user,会导致每次user变化时重复订阅/取消订阅Firebase auth状态,完全没必要。 - 登录成功后手动调用
setUser(email)属于冗余操作,Firebase的onAuthStateChanged监听器会自动同步用户状态。
分步修复代码
1. 修复App.js中的路由传参与useEffect依赖
修改App.js里的路由传参,同时清理useEffect的冗余依赖:
function App() { const [user, setUser] = useState(null); const [authState, setAuthState] = useState(null); useEffect(() => { const unsubscribe = onAuthStateChanged(auth, (authenticatedUser) => { if (authenticatedUser) { setUser(authenticatedUser.email); setAuthState("dashboard"); } else { setUser(null); setAuthState(null); } }); return unsubscribe; }, []); // 移除user依赖,仅在组件挂载/卸载时执行一次 if (authState === null) return ( <> <Navbar /> <div className="container"> <Routes> <Route path="/" element={<Home />} /> {/* 给AdminLogin传入所需props */} <Route path="/AdminLogin" element={<AdminLogin setUser={setUser} setAuthState={setAuthState} />} /> <Route path="/SpielerLogin" element={<SpielerLogin />} /> <Route path="/Spiel" element={<Spiel />} /> <Route path="/HighscoreListe" element={<HighscoreListe />} /> </Routes> </div> </> ); if (user) return ( <> <Dashboard user={user} setAuthState={setAuthState} setUser={setUser} /> </> ); } export default App;
2. 简化AdminLogin的登录逻辑
移除手动调用setUser(email)的冗余代码,依赖Firebase监听器自动同步状态:
import React from "react"; import { signInWithEmailAndPassword } from "firebase/auth"; import { auth } from "../firebase"; export default function AdminLogin({ setAuthState }) { // 不再需要setUser参数 const [email, setEmail] = React.useState(""); const [password, setPassword] = React.useState(""); const handleLogin = (e) => { e.preventDefault(); if (email && password) { // 简化空值判断逻辑 signInWithEmailAndPassword(auth, email, password) .then(() => { setAuthState("dashboard"); // 仅更新auth状态即可 }) .catch((err) => alert(err)); } }; // 其余JSX代码保持不变 }
3. (可选)统一组件名称拼写
Dashboard组件导出名称为DashBoard(大写B),但App.js中使用<Dashboard />,统一拼写更规范:
// Dashboard.js中修改导出名称 export default function Dashboard({ user, setUser, setAuthState }) { const signOutHandler = () => { signOut(auth) .then(() => { setUser(null); setAuthState("login"); }) .catch((err) => console.log(err)); }; // 其余代码保持不变 }
修复后验证
- 输入正确邮箱密码登录,控制台不再抛出
setUser is not a function错误 - 用户登录成功后自动跳转到Dashboard页面
- 退出登录功能正常执行
内容的提问来源于stack exchange,提问作者Hoax
相关产品推荐
相关产品推荐

