React Native管理员登录短暂显示客户端页面及代码重构求助
问题分析与代码重构
核心问题
- 管理员登录时短暂显示客户端页面:初始
user状态为null,默认渲染UserNavi,待Firestore用户数据加载完成后才切换到AdminNavi - 登出后跳转至客户端页面:未认证时默认渲染
UserNavi而非登录页 - 重复监听Auth状态:
SignIn和App组件都存在onAuthStateChanged监听,导致导航逻辑冲突
重构后的App组件代码
import React from 'react'; import { View, ActivityIndicator } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import auth from '@react-native-firebase/auth'; import firestore from '@react-native-firebase/firestore'; import AdminNavi from './AdminNavi'; // 替换为你的导航组件路径 import UserNavi from './UserNavi'; // 替换为你的导航组件路径 import SignIn from './SignIn'; // 替换为你的登录组件路径 const App = () => { const [user, setUser] = React.useState(null); const [isLoading, setIsLoading] = React.useState(true); useEffect(() => { const unsubscribe = auth.onAuthStateChanged(async (authUser) => { setIsLoading(true); if (authUser) { // 从Firestore获取用户角色数据 const userDoc = await firestore.collection("users").doc(authUser.uid).get(); setUser(userDoc.data()); } else { setUser(null); } setIsLoading(false); }); return unsubscribe; }, []); // 加载状态下显示加载指示器 if (isLoading) { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <ActivityIndicator size="large" color="#0000ff" /> </View> ); } return ( <NavigationContainer independent={true}> {user ? ( // 根据用户角色渲染对应导航 user.role === 'admin' ? <AdminNavi /> : <UserNavi /> ) : ( // 未认证时渲染登录页 <SignIn /> )} </NavigationContainer> ); }; export default App;
重构后的SignIn组件代码
import React from 'react'; import { View, TextInput, Button, Alert } from 'react-native'; import auth from '@react-native-firebase/auth'; const SignIn = () => { const [email, setEmail] = React.useState(''); const [password, setPassword] = React.useState(''); const handleLogin = async () => { try { await auth.signInWithEmailAndPassword(email, password); // 登录成功后无需手动导航,App组件会根据Auth状态自动切换页面 setEmail(''); setPassword(''); } catch (error) { Alert.alert('登录失败', error.message); } }; return ( <View style={{ flex: 1, justifyContent: 'center', paddingHorizontal: 20 }}> <TextInput placeholder="邮箱" value={email} onChangeText={setEmail} keyboardType="email-address" autoCapitalize="none" style={{ borderBottomWidth: 1, marginBottom: 15, paddingVertical: 8 }} /> <TextInput placeholder="密码" value={password} onChangeText={setPassword} secureTextEntry style={{ borderBottomWidth: 1, marginBottom: 25, paddingVertical: 8 }} /> <Button title="登录" onPress={handleLogin} /> </View> ); }; export default SignIn;
关键优化点
- 统一Auth状态管理:仅在
App组件中监听onAuthStateChanged,避免重复监听导致的导航冲突 - 添加加载状态:用户数据加载完成前显示加载指示器,解决管理员登录时的页面闪烁问题
- 修正路由逻辑:未认证时直接渲染登录页,登出后自动跳转至登录界面
- 简化登录组件:
SignIn仅负责登录操作,路由逻辑交由App组件统一处理
内容的提问来源于stack exchange,提问作者Bashamlan Salem
相关产品推荐
相关产品推荐

