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
相关产品推荐
相关产品推荐

