React与Firebase实现:仅在登录成功后显示组件
嘿,听起来你已经把基础的登录状态管理和条件渲染搞定了,这很棒!针对你这个台球联盟应用的场景,我给你几个实用的优化建议,让你的登录状态管理更健壮、适配业务需求:
你现在手动维护loggedIn状态虽然能跑,但Firebase Auth本身提供了实时监听用户登录状态的能力,能自动处理用户在其他标签页登出、token过期这类场景,避免手动同步的误差。示例代码:
componentDidMount() { // 订阅登录状态变化 this.authUnsubscribe = firebase.auth().onAuthStateChanged(user => { this.setState({ loggedIn: !!user }); }); } componentWillUnmount() { // 组件卸载时取消订阅,防止内存泄漏 this.authUnsubscribe(); }
这样你甚至不用给loggedIn设默认值,Firebase会自动根据实际登录状态更新你的state。
如果你的赛事计算工具、球队管理等组件都需要访问登录状态,把状态放在父组件逐层传props会越来越麻烦。可以用React Context做全局共享:
先创建AuthContext:
import React, { createContext, useState, useEffect } from 'react'; import firebase from 'firebase/app'; import 'firebase/auth'; export const AuthContext = createContext(); export const AuthProvider = ({ children }) => { const [loggedIn, setLoggedIn] = useState(false); const [user, setUser] = useState(null); useEffect(() => { const unsubscribe = firebase.auth().onAuthStateChanged(user => { setLoggedIn(!!user); setUser(user); }); return unsubscribe; }, []); return ( <AuthContext.Provider value={{ loggedIn, user }}> {children} </AuthContext.Provider> ); };
然后在根组件包裹你的应用,子组件里直接用useContext(AuthContext)就能获取状态,不用层层传props了。
你的赛事工具、球队管理都是登录后才能用的功能,最好给这些路由加保护,未登录用户访问时自动跳转到登录页(如果用React Router的话):
import { Route, Redirect } from 'react-router-dom'; import { useContext } from 'react'; import { AuthContext } from './AuthContext'; const PrivateRoute = ({ component: Component, ...rest }) => { const { loggedIn } = useContext(AuthContext); return ( <Route {...rest} render={props => loggedIn ? <Component {...props} /> : <Redirect to="/login" /> } /> ); }; // 使用方式 <PrivateRoute path="/tournament-calculator" component={TournamentCalculator} /> <PrivateRoute path="/team-management" component={TeamManagement} />
因为你给loggedIn设了默认值false,应用加载时可能会先显示“未登录”的内容,然后瞬间切换到已登录状态,体验不太好。可以在组件初始化时先检查Firebase的当前用户:
componentDidMount() { // 先获取当前已登录的用户(如果有) const currentUser = firebase.auth().currentUser; this.setState({ loggedIn: !!currentUser }); // 再订阅状态变化 this.authUnsubscribe = firebase.auth().onAuthStateChanged(user => { this.setState({ loggedIn: !!user }); }); }
这样能大幅减少页面加载时的状态闪烁问题。
既然只有登录用户才能访问功能,别忘了给Firebase的数据库(Firestore/Realtime Database)设置安全规则,确保未登录用户不能读写数据。比如Firestore的基础规则:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.auth != null; } } }
后续还能根据用户角色(比如管理员、普通球员)设置更细粒度的规则,比如只有管理员能修改球队信息。
这些建议应该能帮你把登录状态管理和应用安全性做得更完善,适配台球联盟应用的需求~
内容的提问来源于stack exchange,提问作者mwojo

