You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 20:44:52