React Native结合Firebase实现Expo用户认证导航时报错如何修复
报错原因
- 核心问题:你在
App组件的return语句中直接返回了firebase.auth().onAuthStateChanged()的执行结果,该方法的返回值是取消监听的函数,不属于合法的React渲染节点,因此触发了「函数不能作为React子元素」的报错。 - 逻辑缺陷:
onAuthStateChanged是异步事件监听器,你不能直接将监听回调内返回的JSX作为组件的渲染结果,回调的执行不会触发组件重新渲染,即使修改写法也无法动态切换登录/首页状态。 - 冗余问题:原代码中声明了两个
NavigationContainer,全局只需保留一个即可。
修复方案
配合React的状态钩子存储登录状态,用副作用钩子注册/清理监听,再根据状态值返回对应的导航节点即可,修复后的完整代码如下:
import { StatusBar } from 'expo-status-bar'; import React, { useState, useEffect } from 'react'; import { StyleSheet, Text, View, ActivityIndicator } from 'react-native'; import { Login } from './login'; import { PageOne } from './pageOne'; import { PageTwo } from './pageTwo'; import 'react-native-gesture-handler'; import { createStackNavigator } from '@react-navigation/stack'; import { NavigationContainer } from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { firebase } from './fbConfig'; const Stack = createStackNavigator(); const Tab = createBottomTabNavigator(); export default function App() { // 存储登录用户信息 const [user, setUser] = useState(null); // 存储初始化加载状态,避免登录页闪屏 const [loading, setLoading] = useState(true); useEffect(() => { // 注册登录状态监听 const unsubscribe = firebase.auth().onAuthStateChanged(authenticate => { setUser(authenticate); setLoading(false); }); // 组件销毁时移除监听,避免内存泄漏 return unsubscribe; }, []); // 初始化加载阶段展示Loading if (loading) { return ( <View style={styles.container}> <ActivityIndicator size="large" /> </View> ); } return ( <NavigationContainer> {user ? ( <Tab.Navigator> <Tab.Screen name="PageOne" component={PageOne} /> <Tab.Screen name="PageTwo" component={PageTwo} /> </Tab.Navigator> ) : ( <Stack.Navigator> <Stack.Screen name="Login" component={Login} /> </Stack.Navigator> )} </NavigationContainer> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });
额外注意事项
- React自定义组件要求首字母大写,原代码中
login、pageOne、pageTwo均为小写开头,会被识别为原生标签导致异常,需要修改为首字母大写的命名,同时对应的组件文件内的导出命名也要同步修改。
内容的提问来源于stack exchange,提问作者Squaredot
相关产品推荐
相关产品推荐

