React-Native调用getAccount出现Cannot read property 'then' of undefined错误
问题排查:React-Native中调用getAccount出现'Cannot read property 'then' of undefined'错误
问题描述
在React-Native项目的App.tsx文件中调用getAccount函数检查用户登录状态时,抛出错误:Cannot read property 'then' of undefined。登录页面使用authenticate函数实现登录功能一切正常,但调用getAccount时,函数内部的日志完全没有输出。
错误原因分析
- Context作用域错误:App组件在
AccountContextProvider的外部就调用了React.useContext(AccountContext),此时获取到的是Context初始化时定义的空函数(const getAccount: any = () => {};),而非Provider内部实现的异步函数。调用这个空函数会返回undefined,自然无法调用.then()方法。 - 组件嵌套逻辑问题:App组件被作为导航栈的一个Screen('App')注册,这会导致循环渲染风险,同时进一步加剧Context作用域的混乱。
解决方案
- 调整Context Provider的位置:将
AccountContextProvider提升到App组件的最外层,确保App组件及其内部所有子组件都能访问到Provider提供的正确上下文值。 - 移除循环渲染的Screen:删除导航栈中不必要的'App' Screen,避免组件循环引用。
- 优化useEffect逻辑:确保useEffect的依赖项合理,避免不必要的重复触发。
修正后的关键代码
修正后的App.tsx
import { StatusBar } from 'expo-status-bar'; import { StyleSheet, Text, View } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import LoginPage from './pages/login'; import sessions from './pages/sessions'; import { AccountContextProvider } from './context/account'; import { EventProvider } from 'react-native-outside-press'; import { FilterContextProvider } from './context/filter'; import { AccountContext } from './context/account'; import React from 'react'; import { getUserAPI } from './api/user'; export type RootStackParamList = { 'Login Page': undefined; 'Sessions Page': { user: any }; }; const Stack = createNativeStackNavigator<RootStackParamList>(); const AppContent = () => { const [user, setUser] = React.useState<any>(undefined); const { getAccount, isLogged } = React.useContext(AccountContext); const getUser = async (session: any) => { const data = await getUserAPI(session); setUser(data); }; React.useEffect(() => { console.log("getting account") getAccount().then((session: any) => { console.log("account got") getUser(session); }) .catch(() => setUser(undefined)); }, [isLogged, getAccount]); return ( <NavigationContainer> <Stack.Navigator initialRouteName={user ? 'Sessions Page' : 'Login Page'} screenOptions={{headerShown: false}}> <Stack.Screen name={'Login Page'} component={LoginPage} /> <Stack.Screen name={'Sessions Page'} component={sessions} initialParams={{user: user}} /> </Stack.Navigator> </NavigationContainer> ); } const App = () => { return ( <AccountContextProvider> <EventProvider> <FilterContextProvider> <AppContent /> </FilterContextProvider> </EventProvider> </AccountContextProvider> ); } export default App; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });
说明
- 将原App组件拆分为
App和AppContent,AccountContextProvider包裹在最外层,确保AppContent能获取到正确的上下文。 - 移除了导航栈中的'App' Screen,避免循环渲染。
- 调整了导航栈的初始路由,根据
user状态自动跳转登录页或会话页。 - 在useEffect的依赖项中添加了
getAccount,确保上下文更新时能重新触发逻辑。
内容的提问来源于stack exchange,提问作者tromborg
相关产品推荐
相关产品推荐

