React Native底部Tab导航点击空白区域自动返回首页问题
问题描述
我使用TypeScript开发React Native应用,配置了Bottom Tab Navigator,包含Home、Explore、Tickets、Profile四个页面。当点击Tickets等页面的空白区域时,应用会自动跳转回Home页面。
开发环境
- 系统:macOS Sonoma 14.4.1
- 设备:MacBook Air
- 芯片:Apple M2
- 内存:8GB
依赖版本
"react-native": "0.74.2""@react-navigation/bottom-tabs": "^6.5.20"
相关代码
AppStack.tsx
import React from "react"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import { AppStackParamList } from "@src/types"; import { SearchEvent } from "@src/screens"; import { BottomStack } from "./BottomStack"; import { EventDetails } from "@src/screens/event-detail/EventDetails"; import { useNavigationLogger } from "@src/hooks/useNavigationLogger"; const { Navigator, Screen } = createNativeStackNavigator<AppStackParamList>(); export function AppStack(): React.JSX.Element { useNavigationLogger(); return ( <Navigator screenOptions={{ headerShown: false }} initialRouteName="BottomStack"> <Screen name="BottomStack" component={BottomStack} /> <Screen name="EventDetail" component={EventDetails} /> <Screen name="SearchEvent" component={SearchEvent} /> </Navigator> ); }
BottomStack.tsx
import React from "react"; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; import { AppStackParamList } from "@src/types"; import { Home, Explore, Tickets, Profile } from "@src/screens"; import OcticonsHomeIcon from "react-native-vector-icons/Octicons"; import AntDesignSearchIcon from "react-native-vector-icons/AntDesign"; import MaterialCommunityIconsTicketIcon from "react-native-vector-icons/MaterialCommunityIcons"; import AntDesignProfileIcon from "react-native-vector-icons/AntDesign"; import { ViewStyle } from "react-native"; import { colors } from "@src/utils"; interface IconProps { focused: boolean; color: string; size: number; } const HomeIcon: React.FC<IconProps> = ({ focused, color, size }) => ( <OcticonsHomeIcon name={focused ? "home" : "home"} size={size} color={color} /> ); const SearchIcon: React.FC<IconProps> = ({ focused, color, size }) => ( <AntDesignSearchIcon name={focused ? "search1" : "search1"} size={size} color={color} /> ); const TicketIcon: React.FC<IconProps> = ({ focused, color, size }) => ( <MaterialCommunityIconsTicketIcon name={focused ? "ticket-confirmation" : "ticket-confirmation"} size={size} color={color} /> ); const ProfileIcon: React.FC<IconProps> = ({ focused, color, size }) => ( <AntDesignProfileIcon name={focused ? "user" : "user"} size={size} color={color} /> ); const screenOptions = ({ route }: { route: any }) => ({ tabBarIcon: ({ focused, color, size }: IconProps) => { switch (route.name) { case "Home": return <HomeIcon focused={focused} color={color} size={size} />; case "Explore": return <SearchIcon focused={focused} color={color} size={size} />; case "Tickets": return <TicketIcon focused={focused} color={color} size={size} />; case "Profile": return <ProfileIcon focused={focused} color={color} size={size} />; default: return null; } }, tabBarActiveTintColor: colors.primary, tabBarInactiveTintColor: colors.textSecondary, headerShown: false, tabBarLabelStyle: { fontSize: 12, }, tabBarStyle: { height: 60, backgroundColor: colors.black, justifyContent: "center", borderTopWidth: 0, } as ViewStyle, }); const BottomTab = createBottomTabNavigator<AppStackParamList>(); export function BottomStack(): React.ReactElement { return ( <BottomTab.Navigator initialRouteName="Home" screenOptions={screenOptions}> <BottomTab.Screen name="Home" component={Home} /> <BottomTab.Screen name="Explore" component={Explore} /> <BottomTab.Screen name="Tickets" component={Tickets} /> <BottomTab.Screen name="Profile" component={Profile} /> </BottomTab.Navigator> ); }
Tickets.tsx
import React from "react"; import { Text, View } from "react-native"; export function Tickets({}): React.JSX.Element { console.log("Tickets screen rendered"); return ( <View style={{ justifyContent: "center", alignItems: "center", flex: 1 }}> <Text>this is Tickets screen</Text> </View> ); }
Profile.tsx
import { Nf3Button } from "@src/components/common"; import React from "react"; import { Text, View } from "react-native"; import { useAppDispatch } from "@src/hooks"; import { logout } from "@src/store/slices/user-slice"; export function Profile({}): React.JSX.Element { const dispatch = useAppDispatch(); return ( <View style={{ justifyContent: "center", alignItems: "center", flex: 1 }}> <Text>this is profile screen</Text> <Nf3Button title="logout" style={{ alignSelf: "center" }} onPress={() => dispatch(logout())} /> </View> ); }
useNavigationLogger.ts
import { useEffect } from "react"; import { useNavigation, useNavigationState } from "@react-navigation/native"; export function useNavigationLogger() { const navigation = useNavigation(); const state = useNavigationState((state) => state); useEffect(() => { const unsubscribe = navigation.addListener("state", () => { console.log("Navigation state changed:", JSON.stringify(state, null, 2)); }); return unsubscribe; }, [navigation, state]); }
导航日志
切换到Tickets页面时:
LOG Tickets screen rendered LOG Navigation state changed: undefined
点击Tickets页面空白区域后:
LOG Navigation state changed: { "stale": false, "type": "stack", "key": "stack-mb5sp5e4a4kn9dj_0kHvK", "index": 0, "routeNames": [ "BottomStack", "EventDetail", "SearchEvent" ], "routes": [ { "key": "BottomStack-VQT1LwwFSP7qtfSF10J6h", "name": "BottomStack", "state": { "stale": false, "type": "tab", "key": "tab-euFwrJf651_yFCB2jAHQJ", "index": 2, "routeNames": [ "Home", "Explore", "Tickets", "Profile" ], "history": [ { "type": "route", "key": "Home-qKX3M5AQ2M5H9ATqwSzi6" }, { "type": "route", "key": "Tickets-X9PZhIsfM7R4O4HJtEfI_" } ], "routes": [ { "name": "Home", "key": "Home-qKX3M5AQ2M5H9ATqwSzi6" }, { "name": "Explore", "key": "Explore-oxyMhsKyagZFlG5oXrFPM" }, { "name": "Tickets", "key": "Tickets-X9PZhIsfM7R4O4HJtEfI_" }, { "name": "Profile", "key": "Profile-5BhwfhOYgLMcFIFt-5Adq" } ] } } ] }
内容的提问来源于stack exchange,提问作者kryptonian
相关产品推荐
相关产品推荐

