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

React Native访问Admin Dashboard页面出现白屏问题求助

React Native 角色导航白屏问题

近期在React Native项目中实现了基于用户角色(admin和user)的页面导航逻辑,但admin登录后访问Admin Dashboard时页面仅显示白屏。相关代码如下:

App.js

import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import React, { useEffect, useState } from "react";
import { firebase, db } from './config'

import Login from './Screens/Login';
import Registration from './Screens/Registration';
import Dashboard from './Screens/Dashboard';
import UserDashboard from './Screens/UserDashboard';
import ProfileScreen from './Screens/Profile';
import JobScreen from './app/index';

import Header from './Header';

const Stack = createStackNavigator();

function App() {
    const [initializing, setInitializing] = useState(true);
    const [user, setUser] = useState(null);
    const [role, setRole] = useState(null);

    function onAuthStateChanged(user) {
        setUser(user);
        if (initializing) setInitializing(false);
    }

    useEffect(() => {
        const subscriber = firebase.auth().onAuthStateChanged(onAuthStateChanged);
        return subscriber;
    }, []);

    useEffect(() => {
        if (user) {
            const unsubscribe = firebase
                .firestore()
                .collection("users")
                .doc(user.uid)
                .onSnapshot((doc) => {
                    const userData = doc.data();
                    setRole(userData?.role);
                });
            return unsubscribe;
        }
    }, [user]);

    if (initializing) {
        return null; // 可替换为加载 spinner
    }

    if (!user) {
        return (
            <Stack.Navigator>
                <Stack.Screen
                    name="Login"
                    component={Login}
                    options={{
                        headerTitle: () => (
                            <Header name=" Welcome to the Industrial King " />
                        ),
                        headerStyle: {
                            height: 150,
                            borderBottomLeftRadius: 50,
                            borderBottomRightRadius: 50,
                            backgroundColor: "#00e4d0",
                            shadowColor: "#000",
                            elevation: 25,
                        },
                    }}
                />
                <Stack.Screen
                    name="Registration"
                    component={Registration}
                    options={{
                        headerTitle: () => (
                            <Header name="Please fill out all details below " />
                        ),
                        headerStyle: {
                            height: 150,
                            borderBottomLeftRadius: 50,
                            borderBottomRightRadius: 50,
                            backgroundColor: "#00e4d0",
                            shadowColor: "#000",
                            elevation: 25,
                        },
                    }}
                />
            </Stack.Navigator>
        );
    }

    switch (role) {
        case "admin":
            return (
                <Stack.Navigator>
                    <Stack.Screen
                        name="Dashboard"
                        component={Dashboard}
                        options={{
                            headerTitle: () => (
                                <Header name=" Admin Dashboard " />
                            ),
                            headerStyle: {
                                height: 150,
                                borderBottomLeftRadius: 50,
                                borderBottomRightRadius: 50,
                                backgroundColor: "#00e4d0",
                                shadowColor: "#000",
                                elevation: 25,
                            },
                        }}
                    />
                    <Stack.Screen
                        name="Profile"
                        component={ProfileScreen}
                        options={{
                            headerTitle: () => <Header name="Profile " />,
                            headerStyle: {
                                height: 150,
                                borderBottomLeftRadius: 50,
                                borderBottomRightRadius: 50,
                                backgroundColor: "#00e4d0",
                                shadowColor: "#000",
                                elevation: 25,
                            },
                        }}
                    />
                    <Stack.Screen name="Job" component={JobScreen} />
                </Stack.Navigator>
            );
        case "user":
            return (
                <Stack.Navigator>
                    <Stack.Screen
                        name="UserDashboard"
                        component={UserDashboard}
                        options={{
                            headerTitle: () => <Header name="Profile " />,
                            headerStyle: {
                                height: 150,
                                borderBottomLeftRadius: 50,
                                borderBottomRightRadius: 50,
                                backgroundColor: "#00e4d0",
                                shadowColor: "#000",
                                elevation: 25,
                            },
                        }}
                    />
                </Stack.Navigator>
            );
        default:
            return null;
    }
}

export default () => {
    return (
        <NavigationContainer independent={true}>
            <App />
        </NavigationContainer>
    );
}

Dashboard.js

import React, { useEffect, useState } from "react";
import { View, Text, TouchableOpacity, TextInput, StyleSheet } from 'react-native';
import { SafeAreaView } from "react-native-safe-area-context";
import { firebase } from '../config';
import { useNavigation } from '@react-navigation/native';

const Dashboard = () => {
    const [name, setName] = useState('')
    const navigation = useNavigation();

    // 修改用户密码
    const changePassword = () => {
        firebase.auth().sendPasswordResetEmail(firebase.auth().currentUser.email)
        .then(() => {
            alert("密码重置邮件已发送")
        }).catch((error) => {
            alert(error.message)
        })
    }

    useEffect(() => {
        firebase.firestore().collection('users')
        .doc(firebase.auth().currentUser.uid).get()
        .then((snapshot) => {
            if (snapshot.exists) {
                setName(snapshot.data().name) // 修正:取name字段而非整个对象
            } else {
                console.log('用户不存在')
            }
        })
    }, [])

    return (
        <SafeAreaView>
            <TouchableOpacity
                onPress={() => {
                changePassword()
                }}>
            </TouchableOpacity>

            <TouchableOpacity
                onPress={() => navigation.navigate('index')}
                style={styles.button}>
                <Text style={{ fontSize: 22, fontWeight: 'bold' }}>
                    搜索职位
                </Text>
            </TouchableOpacity>

            <TouchableOpacity
                onPress={() => navigation.navigate('Profile')}
                style={styles.button}>
                <Text style={{ fontSize: 22, fontWeight: 'bold' }}>
                    查看个人资料
                </Text>
            </TouchableOpacity>
            <TouchableOpacity
                onPress={() => { firebase.auth().signOut() }}
                style={styles.button}>
                <Text style={{ fontSize: 22, fontWeight: 'bold' }}>
                    退出登录
                </Text>
            </TouchableOpacity>
        </SafeAreaView>
    )
}

export default Dashboard

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        marginTop: 100,
    },
    button: {
        marginTop: 50,
        height: 70,
        width: 250,
        backgroundColor: '#026efd',
        alignItems: 'center',
        justifyContent: 'center',
        borderRadius: 50,
    }
})

Firebase.Config

import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';

// Firebase 配置
const firebaseConfig = {
    apiKey: "AIzaSyAMTzGwM8KlZdKhk4EowjlaOgLaeDBnBDU",
    authDomain: "honsprojectfinal.firebaseapp.com",
    databaseURL: "https://honsprojectfinal-default-rtdb.asia-southeast1.firebasedatabase.app",
    projectId: "honsprojectfinal",
    storageBucket: "honsprojectfinal.appspot.com",
    messagingSenderId: "214071266814",
    appId: "1:214071266814:web:f4cbe25a3e124ca8a044af",
    measurementId: "G-TVF8SE9809"
};

if (!firebase.apps.length){
    firebase.initializeApp(firebaseConfig);
}

const db = firebase.firestore();

// 存储用户角色的集合
const rolesRef = db.collection('roles');

export { firebase, db, rolesRef };

问题排查与修复方案

1. 角色加载间隙的白屏

App.js中,当Firestore还未返回用户角色时,role为null,会进入switch的default分支返回null,导致页面空白。

修复:
替换default分支的返回值,添加加载状态:

default:
    return (
        <View style={{flex:1, justifyContent:'center', alignItems:'center'}}>
            <Text>加载中...</Text>
        </View>
    );

2. Dashboard组件布局异常

Dashboard.js中的SafeAreaView未设置flex:1,且第一个TouchableOpacity为空,导致内容无法正常显示。

修复:

  • 给SafeAreaView应用styles.container样式,确保布局占满屏幕:
<SafeAreaView style={styles.container}>
  • 给空的TouchableOpacity添加内容和样式,或直接移除:
<TouchableOpacity onPress={changePassword} style={styles.button}>
    <Text style={{ fontSize: 22, fontWeight: 'bold' }}>重置密码</Text>
</TouchableOpacity>

3. 导航跳转目标错误

Dashboard.js中调用navigation.navigate('index'),但App.js的栈中注册的页面名称是Job,而非index,会触发导航错误导致白屏。

修复:
修改跳转目标为正确的页面名称:

onPress={() => navigation.navigate('Job')}

4. 用户名称设置错误

Dashboard.js的useEffect中,setName(snapshot.data())将整个用户对象赋值给name,后续若渲染name会引发错误。

修复:
仅赋值用户名称字段:

setName(snapshot.data().name)

5. 角色默认值兜底

在App.js获取角色时,若userData?.role为undefined,会导致role为undefined,进入default分支。

优化:
给角色设置默认值,避免空值:

setRole(userData?.role || 'user');

内容的提问来源于stack exchange,提问作者Steven McWilliams

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 08:24:58