React Native导航报错Car路由未被任何导航器处理如何解决
React Native 跳转Car页面导航报错修复
报错根因
抛出"NAVIGATE" {"name":"Car"} Was not handled by any navigator的本质是:调用跳转方法时,当前活跃的导航栈里根本没有注册Car这个路由,导航器找不到对应处理逻辑。代码里一共存在5个直接导致问题的错误:
- 登录成功后刚把token写入本地存储,立刻调用
navigation.navigate('Car'),此时根导航还停留在未登录的Auth认证栈,Auth栈里只注册了Login、Forget两个页面,Car属于登录后才挂载的Main栈,还没被渲染到导航树里,自然找不到。 - Auth栈的页面注册语法错误:定义的导航容器是
AuthStack,写Screen的时候却用了未定义的Stack.Screen,会导致Auth栈本身渲染异常。 - 底部Tab导航配置错误:给Tab导航设置的初始路由是
Car,但Tab里只注册了Start、Driver两个页面,Car是和Tab平级、注册在MainStack里的页面,根本不在Tab的路由表里,就算切到主栈也会先抛初始路由不存在的错误。 - 根导航组件
Navigation1是直接包裹在NavigationContainer下的顶层组件,外层没有任何导航器,根本拿不到navigation属性,写的启动自动跳Login的逻辑本身就会报navigation.navigate is not a function的错,而且完全多余——未登录状态下默认渲染的就是Auth栈,第一个页面就是Login,不需要手动跳转。 - 写了100ms一次的轮询读本地存储的逻辑,既耗性能,也解决不了登录状态更新和导航挂载的时序问题。
分步修复
1. 修正基础语法和配置错误
首先修正Auth栈的Screen引用错误:
const AuthStackScreen = () => ( <AuthStack.Navigator screenOptions={{ headerStyle: { backgroundColor: 'white', height: 47, }, }}> {/* 把原来错误的Stack.Screen全部替换成AuthStack.Screen */} <AuthStack.Screen name="Login" component={Login} options={{title: 'Dashboard', headerShown: false}} /> <AuthStack.Screen name="Forget" component={ForgetPassword} options={{title: 'Dashboard', headerShown: false}} /> </AuthStack.Navigator> );
然后修正底部Tab的初始路由配置,把不存在的Car替换成已注册的页面:
<Tab.Navigator initialRouteName={'Start'} // 原来写的'Car'删掉,Tab内没有注册这个路由 lazy={true} tabBarOptions={{/* 原有配置保留 */}} >
删掉Tab按钮上多余的tabPress监听:写的e.preventDefault()再手动navigate完全是重复逻辑,Tab默认就会处理跳转,加了反而可能导致点击无响应,直接把两个Tab.Screen下的listeners配置删掉即可。
2. 替换登录成功的跳转逻辑
登录属于全局导航状态切换,不要直接在登录页调用navigate跳内页,用navigation.reset直接替换整个导航栈,既能清空之前的认证栈历史(避免用户按返回键回到登录页),也能确保跳Car的时候Main栈已经完成挂载:
.then(async response2 => { setLoading(false); if (response2.data.email) { try { await AsyncStorage.setItem('@storage_Key', data.token); await AsyncStorage.setItem( '@storage_Key_refresh', data.refresh_token, ); // 重置导航栈,先加载主栈,再跳转到Car页面 navigation.reset({ index: 1, routes: [ { name: 'Main' }, { name: 'Car' } ] }) } catch (error) { console.log('AsyncStorage Error: ' + error.message); } } else { setLoading(false); Alert.alert( '登录成功', '抱歉,你没有Digital fleet的访问权限', ); } })
3. 重构根导航的状态逻辑
删掉根组件里无效的navigation参数、没用的轮询逻辑、多余的跳转effect,只保留挂载时一次读取本地存储判断登录状态的逻辑即可,核心代码如下:
// 去掉多余的navigation入参,根组件拿不到这个prop function Navigation1() { const [hasLoginToken, setHasLoginToken] = React.useState(null); const [loading, setLoading] = React.useState(true); React.useEffect(() => { const readData = async () => { try { const userToken = await AsyncStorage.getItem('@storage_Key'); setHasLoginToken(!!userToken); } catch (e) { setHasLoginToken(false); console.log('读取本地存储失败 ', e); } finally { setLoading(false); } }; // 组件挂载时读一次即可,不需要轮询 readData(); }, []); // 原有AuthStackScreen、MainStackScreen定义保留,记得修正之前说的AuthStack.Screen错误 const AuthStack = createStackNavigator(); const AuthStackScreen = () => ( <AuthStack.Navigator screenOptions={{headerStyle: {backgroundColor: 'white', height: 47}}}> <AuthStack.Screen name="Login" component={Login} options={{headerShown: false}}/> <AuthStack.Screen name="Forget" component={ForgetPassword} options={{headerShown: false}}/> </AuthStack.Navigator> ); const MainStack = createStackNavigator(); const MainStackScreen = () => ( <MainStack.Navigator screenOptions={{headerStyle: {backgroundColor: 'white', height: 45}}}> <MainStack.Screen name="Home" component={BottomNavigation} options={{headerShown: false}}/> <MainStack.Screen name="Car" component={Car} options={{headerShown: false}}/> </MainStack.Navigator> ); const RootStack = createStackNavigator(); const network = OfflineNotice(); if (network === false) { return <Screen />; } // 加载中返回空或者自定义启动页,避免导航栈切换时闪屏 if (loading) return null; return ( <NavigationContainer> <RootStack.Navigator screenOptions={{headerShown: false}}> {hasLoginToken ? ( <RootStack.Screen name="Main" component={MainStackScreen} /> ) : ( <RootStack.Screen name="Auth" component={AuthStackScreen} /> )} </RootStack.Navigator> </NavigationContainer> ); } export default Navigation1;
额外注意
退出登录时,记得先清除本地存储的token,再用同样的navigation.reset方法把导航栈替换成Auth栈,不要直接navigate到Login,避免路由历史残留导致返回键逻辑异常。
内容的提问来源于stack exchange,提问作者Rahul Raj
相关产品推荐
相关产品推荐

