React Native应用首次启动执行登出操作崩溃,二次启动运行正常
问题根因
- 首次启动分支路由缺少登录态校验:App.js中
isFirstLaunch === true的分支仅固定渲染StackNavigation,登出把userData设为null后,不会像二次启动分支那样自动切换到AuthNavigation,Profile页面始终处于挂载状态。 - Profile组件无空值防护:所有访问
userData.detail.xxx的位置都没有判断userData是否存在,当userData变为null时直接触发空指针错误导致崩溃。 - 登出操作未清理导航栈:登出后没有跳转回登录页,已挂载的Profile组件依然会尝试访问已经被清空的
userData。
修复方案
1. 给Profile组件添加空值防护
所有访问userData属性的位置添加可选链操作符,或者在组件开头判断userData不存在时直接返回占位内容:
function Profile({ navigation }) { const tabheight = useBottomTabBarHeight(); const { userData, setUserData } = useContext(AuthContext); const key = "@storage_Key"; // 新增:userData为空时返回加载态,避免空指针 if (!userData) { return <View style={{flex:1,justifyContent:"center",alignItems:"center"}}> <ActivityIndicator size="large" /> </View> } // 其余代码不变,所有访问userData的位置替换为可选链写法,例如: // {userData?.detail?.first_name + " " + userData?.detail?.last_name} // 其他userData.detail.xxx的位置都做相同修改 }
2. 登出时主动重置导航栈到登录页
修改handleLogOut方法,登出后直接清空导航栈跳转到登录页,确保Profile组件被卸载:
const handleLogOut = () => { setUserData(null); storage.removeData(key); // 替换为你实际的登录页路由名称 navigation.reset({ index: 0, routes: [{ name: 'LoginScreen' }] }) };
3. 统一App.js的路由逻辑(推荐)
不要分首次启动和非首次启动两个分支写两套导航容器逻辑,改为使用同一个导航容器,将首次启动引导页放到全局路由栈中处理,避免两套逻辑差异导致的问题:
// 修改App.js的渲染逻辑,仅保留一个NavigationContainer if (!isReady) return <AppLoading startAsync={getToken} onFinish={() => setIsReady(true)} onError={console.warn} />; return ( <AuthContext.Provider value={{ userData, setUserData }}> <NavigationContainer> {/* 把首次启动判断放到StackNavigation里处理,根栈优先判断是否需要展示引导页,再判断登录态走对应路由 */} <StackNavigation isFirstLaunch={isFirstLaunch} userData={userData} /> </NavigationContainer> </AuthContext.Provider> )
在StackNavigation里补充路由判断逻辑:如果是首次启动走引导页流程,否则判断userData存在就渲染Tabs,不存在就渲染AuthNavigation即可。
内容的提问来源于stack exchange,提问作者GOKUL RAJ K P
相关产品推荐
相关产品推荐

