从Expo SecureStore获取用户ID,判断渲染组件遇逻辑错误
问题根源
你直接在条件渲染里调用doesIdExist()是错误的——async函数的返回值永远是Promise对象,而在JavaScript中,Promise属于“真值”,所以不管实际检查结果是true还是false,条件判断都会走?后的分支,也就是渲染BottomTabNavigator,这就是为什么新用户场景下console输出false却渲染了错误组件的原因。
修复方案
要用React状态来管理异步检查的结果,同时处理加载状态(因为读取SecureStore是异步操作,不能瞬间得到结果)。具体步骤如下:
- 引入
useState和useEffect钩子 - 定义两个状态:
isLoggedIn(存储是否存在用户ID)和isLoading(标记异步操作是否完成) - 在
useEffect中执行异步检查,更新状态 - 渲染时先判断加载状态,加载完成后再根据
isLoggedIn渲染对应导航器
修改后的完整代码
import { useState, useEffect } from 'react'; import { View, ActivityIndicator } from 'react-native'; import * as SecureStore from 'expo-secure-store'; export default function App() { const [isLoggedIn, setIsLoggedIn] = useState(false); const [isLoading, setIsLoading] = useState(true); const checkUserIdExists = async () => { const id = await SecureStore.getItemAsync('userId'); setIsLoggedIn(id !== null); setIsLoading(false); // 异步操作完成,结束加载状态 }; // 组件挂载时执行一次检查 useEffect(() => { checkUserIdExists(); }, []); // 加载中显示加载指示器,避免空白或错误渲染 if (isLoading) { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <ActivityIndicator size="large" /> </View> ); } return ( <View style={styles.container}> {isLoggedIn ? ( <BottomTabNavigator style={styles.tab} /> ) : ( <NavigationContainer> <OnboardingNavigator /> </NavigationContainer> )} </View> ); }
关键说明
- 状态管理:用
isLoggedIn存储最终的判断结果,isLoading确保异步操作完成前不会渲染错误组件 - useEffect的作用:保证仅在组件首次挂载时执行用户ID检查,避免重复调用接口
- 加载状态处理:添加
ActivityIndicator提升用户体验,解决异步操作期间的界面空白问题
内容的提问来源于stack exchange,提问作者chingu
相关产品推荐
相关产品推荐

