嵌套Stack Navigator中BottomTabBar导航引发Hook渲染数量异常
我在项目中使用底部标签栏(Bottom Tab Bar),需要添加一个不在标签栏显示的页面,所以创建了Native Stack并将其初始页面设为Bottom Tab Stack。但使用底部Tab导航时出现如下错误:
Error: Rendered more hooks than during the previous render. This error is located at: in BottomTabView (created by BottomTabNavigator) in PreventRemoveProvider (created by NavigationContent) in NavigationContent in Unknown (created by BottomTabNavigator) in BottomTabNavigator (created by BottomTabs) in BottomTabs (created by SceneView) in StaticContainer in EnsureSingleNavigator (created by SceneView) in SceneView (created by SceneView) in RCTView (created by View) in View (created by DebugContainer) in DebugContainer (created by MaybeNestedStack) in MaybeNestedStack (created by SceneView) in RCTView (created by View) in View (created by SceneView) in RNSScreen (created by AnimatedComponent) in AnimatedComponent in AnimatedComponentWrapper (created by InnerScreen) in Suspender (created by Freeze) in Suspense (created by Freeze) in Freeze (created by DelayedFreeze) in DelayedFreeze (created by InnerScreen) in InnerScreen (created by Screen) in Screen (created by SceneView) in SceneView (created by NativeStackViewInner) in Suspender (created by Freeze) in Suspense (created by Freeze) in Freeze (created by DelayedFreeze) in DelayedFreeze (created by ScreenStack) in RNSScreenStack (created by ScreenStack) in ScreenStack (created by NativeStackViewInner) in NativeStackViewInner (created by NativeStackView) in RCTView (created by View) in View (created by SafeAreaInsetsContext) in SafeAreaProviderCompat (created by NativeStackView) in NativeStackView (created by NativeStackNavigator) in PreventRemoveProvider (created by NavigationContent) in NavigationContent in Unknown (created by NativeStackNavigator) in NativeStackNavigator (created by MainStack) in MainStack (created by App) in RNCSafeAreaView (created by App) in $29383e587d62412a$export$9f8ac96af4b1b2ae (created by NativeBaseProvider) in ToastProvider (created by NativeBaseProvider) in PortalProvider (created by NativeBaseProvider) in HybridProvider (created by NativeBaseProvider) in ResponsiveQueryProvider (created by NativeBaseProvider) in RNCSafeAreaProvider (created by SafeAreaProvider) in SafeAreaProvider (created by NativeBaseProvider) in NativeBaseConfigProviderProvider (created by NativeBaseProvider) in NativeBaseProvider (created by App) in EnsureSingleNavigator in BaseNavigationContainer in ThemeProvider in NavigationContainerInner (created by App) in RNCSafeAreaProvider (created by SafeAreaProvider) in SafeAreaProvider (created by App) in App in RCTView (created by View) in View (created by AppContainer) in RCTView (created by View) in View (created by AppContainer) in AppContainer in promptdrinksMobile(RootComponent), js engine: hermes
将Bottom Tab导航移出嵌套结构后功能完全正常,以下是我的代码配置:
主Stack导航配置
import { createNativeStackNavigator } from '@react-navigation/native-stack' // Stack imports import BottomTabs from './BottomTabNavigator' // Screen imports import DetailScreen from '../screens/DetailScreen' const Stack = createNativeStackNavigator() const MainStack = () => { return ( <Stack.Navigator screenOptions={{ headerShown: false, }} > <Stack.Screen name="BottomTabNavigator" component={BottomTabs} /> <Stack.Screen name="DetailPage" component={DetailScreen} /> </Stack.Navigator> ) } export default MainStack
底部Tab导航配置
import React from 'react' import { createBottomTabNavigator } from '@react-navigation/bottom-tabs' // Config imports import { siteVars } from '../config/siteConfig' // Component imports import TabItem from '../components/tab_bar/TabItem' // Screen imports import Home from '../screens/Home' import Generated from '../screens/Generated' import Settings from '../screens/Settings' // Components import Header from '../components/layout/Header' // Stores const Tab = createBottomTabNavigator() const BottomTabs = () => { return ( <Tab.Navigator initialRouteName={siteVars.generatedName} sceneContainerStyle={{flexGrow: 1}} screenOptions={{ header: Header, tabBarShowLabel: false, tabBarStyle: { height: 20, paddingTop: 30, paddingBottom: 35 } }} > <Tab.Screen name="Home" component={Home} options={{ tabBarIcon: (props) => <TabItem {...props} alt="Home icon" name="Home" logo={require('../assets/logos/home.png')} /> }} /> <Tab.Screen name={siteVars.generatedName} component={Generated} options={{ tabBarIcon: (props) => <TabItem {...props} alt="Generated Icon" name={siteVars.generatedName} logo={require('../assets/logos/generated_logo.png')} /> }} /> <Tab.Screen name="Settings" component={Settings} options={{ tabBarIcon: (props) => <TabItem {...props} alt="Generated Icon" name="Settings" logo={require('../assets/logos/settings.png')} /> }} /> </Tab.Navigator> ) } export default BottomTabs
App入口文件配置
/** * * Generated with the TypeScript template * https://github.com/react-native-community/react-native-template-typescript * * @format */ import React from 'react' import { NavigationContainer } from '@react-navigation/native' import { Modal, NativeBaseProvider, StatusBar } from 'native-base' import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context' // Tabs and Navigators import BottomTabs from './src/navigators/BottomTabNavigator' import MainStack from './src/navigators/MainStackNavigator' // Styles and Themes import theme from './src/styles/theme' const App = () => { return ( <SafeAreaProvider> <NavigationContainer> <NativeBaseProvider theme={theme}> <SafeAreaView edges={['top', 'right', 'left']} style={{flexGrow: 1, backgroundColor: '#333'}}> <StatusBar barStyle="light-content" /> <MainStack /> </SafeAreaView> </NativeBaseProvider> </NavigationContainer> </SafeAreaProvider> ) } export default App;
修复方案
这个错误的核心原因是在底部Tab导航的screenOptions中直接传入Header组件,React Navigation的header属性要求传入一个返回React元素的函数,而非组件本身。嵌套导航场景下,直接传组件会导致Hook调用次数异常,触发错误。
具体修复步骤:
- 修改BottomTabNavigator中的
screenOptions,将header: Header改为header: () => <Header /> - 检查
Header组件内部,确保没有在条件判断、循环等场景中调用Hook(比如useState、useEffect),这也是触发该错误的常见诱因
修改后的底部Tab导航关键代码片段:
<Tab.Navigator initialRouteName={siteVars.generatedName} sceneContainerStyle={{flexGrow: 1}} screenOptions={{ // 将直接传组件改为函数返回组件实例 header: () => <Header />, tabBarShowLabel: false, tabBarStyle: { height: 20, paddingTop: 30, paddingBottom: 35 } }} >
内容的提问来源于stack exchange,提问作者Joel Hager
相关产品推荐
相关产品推荐

