如何借助getRoutName函数在子页面隐藏自定义Header组件
问题解决思路与代码修改
你遇到的核心问题是:在TabsNavigator组件中直接调用useRoute拿到的是Tab导航器自身的路由,而非当前活跃的子页面路由,导致无法正确判断是否需要隐藏Header。下面是具体的解决方案和修改后的代码:
修改后的完整代码
import {Platform, StyleSheet} from 'react-native'; import React, {useEffect, useState} from 'react'; import { getFocusedRouteNameFromRoute, useNavigation, } from '@react-navigation/native'; import GlobalConfig from '../Config/GlobalConfig'; import Header from '../Components/Header'; import AppSafeArea from '../Components/AppSafeArea'; const global = GlobalConfig[GlobalConfig.CURRENT_APP]; const tabs = global.tabs; const colors = global.colors; const currentTab = global.tabType; const tabTypeName = global.tabTypeName; const TabsNavigator = () => { const [isIcon, setIsIcon] = useState(false); const [headerVisible, setHeaderVisible] = useState(true); const navigation = useNavigation(); useEffect(() => { tabTypeName === 'TopTabs' ? setIsIcon(true) : setIsIcon(false); }, [tabTypeName]); // 添加依赖项,避免不必要的重渲染 useEffect(() => { const unsubscribe = navigation.addListener('state', () => { // 获取当前Tab导航器的路由实例 const parentRoute = navigation.getCurrentRoute(); if (!parentRoute) return; // 获取当前聚焦的子路由名称 const routeName = getFocusedRouteNameFromRoute(parentRoute); // 判断是否需要隐藏Header:命中排除列表则隐藏 const shouldHide = routeName && excludedRoutes.some(excluded => routeName.includes(excluded)); setHeaderVisible(!shouldHide); }); // 组件卸载时取消监听,避免内存泄漏 return unsubscribe; }, [navigation]); return ( <> <AppSafeArea /> <Header onPress={() => navigation.navigate('Settings')} visible={headerVisible} /> <currentTab.Navigator screenOptions={{ tabBarActiveTintColor: colors.tertiary, tabBarInactiveTintColor: colors.white, tabBarStyle: styles.tabbar, }}> {tabs.map((tab, index) => { return ( <currentTab.Screen key={index} name={tab.tabName} component={tab.tabComponent} options={({route}) => ({ headerShown: false, tabBarIconStyle: {display: isIcon ? 'none' : 'flex'}, tabBarIcon: ({size, color}) => ( <tab.tabIcon width={20} height={20} fill={color} /> ), tabBarStyle: { display: getRoutName(route), ...styles.tabbar, }, tabBarLabelStyle: {fontSize: 13}, })} /> ); })} </currentTab.Navigator> </> ); }; const styles = StyleSheet.create({ tabbar: { backgroundColor: colors.primary, borderTopWidth: 0, paddingHorizontal: 10, }, }); export default TabsNavigator; const excludedRoutes = [ 'LiveStream', 'AboutChurch', 'PrayerRequest', 'ShareTestimony', 'DevotionalMessages', 'CheckInHistory', 'MakeDonation', 'Pledge', 'GivingHistory', 'SavedPosts', 'AboutTheDeveloper', 'MomoPay', 'CardDetails', 'CardPayment', 'EditProfile', 'MakeRequest', 'RequestForm', 'FeedPreview', 'MoreSettings', 'AddMomoNumber', ]; const getRoutName = route => { const routeName = getFocusedRouteNameFromRoute(route); if (routeName && excludedRoutes.some(route => routeName.includes(route))) { return 'none'; } };
关键修改说明
- 新增
headerVisible状态变量,专门控制Header组件的显示/隐藏 - 通过
navigation.addListener('state', ...)监听导航状态变化,每次路由切换时重新计算Header的显示状态 - 复用已有的
excludedRoutes列表和路由判断逻辑,保证与底部标签栏的隐藏规则一致 - 给第一个
useEffect添加tabTypeName依赖项,避免组件无意义的重复渲染 - 移除了无效的
useRoute调用,改用navigation.getCurrentRoute()获取Tab导航器的路由实例,再通过getFocusedRouteNameFromRoute拿到活跃子路由名称
内容的提问来源于stack exchange,提问作者victor Ofori Acheampong
相关产品推荐
相关产品推荐

