You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native管理员登录短暂显示客户端页面及代码重构求助

问题分析与代码重构

核心问题

  1. 管理员登录时短暂显示客户端页面:初始user状态为null,默认渲染UserNavi,待Firestore用户数据加载完成后才切换到AdminNavi
  2. 登出后跳转至客户端页面:未认证时默认渲染UserNavi而非登录页
  3. 重复监听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;

关键优化点

  1. 统一Auth状态管理:仅在App组件中监听onAuthStateChanged,避免重复监听导致的导航冲突
  2. 添加加载状态:用户数据加载完成前显示加载指示器,解决管理员登录时的页面闪烁问题
  3. 修正路由逻辑:未认证时直接渲染登录页,登出后自动跳转至登录界面
  4. 简化登录组件:SignIn仅负责登录操作,路由逻辑交由App组件统一处理

内容的提问来源于stack exchange,提问作者Bashamlan Salem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 23:50:23