嵌套Drawer、Tab、Stack的导航跳转报Hooks顺序及prevDeps未定义错误
报错根本原因
所有异常的触发核心来自两个叠加问题,共同引发了Hooks顺序警告与运行时错误:
- Stack实例的创建时机错误。当前代码把
const Stack = createStackNavigator()写在了HomeNavigator组件的函数体内部,每次组件重渲染都会执行这个工厂函数,生成全新的Stack导航器实例。因为根导航配置中Main路由是条件渲染的(依赖isApplicationLoaded、BeforeLogin的状态),一旦这两个状态变化触发重渲染,新生成的Stack实例内部挂载的所有Hooks,会和上一次渲染时的Hooks调用顺序完全错位,直接触发React的Hooks顺序变更警告;当React尝试比对上一次的Hooks依赖数组时,因为新旧实例完全不对应,拿到的prevDeps值为undefined,就会触发TypeError: undefined is not an object (evaluating 'prevDeps.length')的运行时崩溃。 - 导航树状态被破坏后,路由匹配逻辑完全失效,自然无法完成嵌套跳转。
嵌套跳转失败的原因
当前的导航嵌套层级为:
Drawer.Navigator -> Drawer.Screen(name="Main",对应TabNavigator) -> Tab.Screen(name="Home",对应HomeStack) -> Stack.Screen(name="Events")
现有跳转代码navigation.navigate('Home', { screen: 'Events' })没有指定最上层的Main路由作为入口,导航器根本定位不到嵌套的Home路由层级;再加之前Stack实例反复重建导致导航状态树损坏,最终表现为跳转无响应、触发运行错误。
修复方案
- 调整Stack实例的创建位置:把
createStackNavigator()的调用移动到模块顶层、组件定义的外部,整个应用加载时只生成一次Stack实例,所有渲染周期复用同一个实例,从根源解决Hooks顺序错乱的问题。示例代码:
// 模块顶层,组件外部执行一次 const Stack = createStackNavigator() const HomeNavigator = () => { const { t } = useTranslation() return ( <Stack.Navigator> <Stack.Screen options={headerStyle_1} name='Index' title={t('title.homepage')} component={HomepageController} /> <Stack.Screen options={headerStyle_1} name='Events' title={t('title.events')} component={EventsController} /> </Stack.Navigator> ) }
- 修正嵌套跳转的完整路径:跳转时必须把所有上级嵌套路由的层级参数写全,对应你的导航结构正确的跳转代码为:
<TouchableOpacity style={styles.accessButton} onPress={() => navigation.navigate('Main', { screen: 'Home', params: { screen: 'Events' } })} >
- 兼容TabNavigator的配置写法:当前代码中的
tabBarOptions是React Navigation v4及更早版本的配置属性,v5/v6版本已经替换为screenOptions下的对应配置,建议同步调整避免后续出现其他兼容问题。
内容的提问来源于stack exchange,提问作者TCS
相关产品推荐
相关产品推荐

