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

如何在Material Top Tabs中嵌套Expo Tabs?路由结构求助

解决Expo Router中顶部Tabs嵌套底部Tabs的路由配置问题

正确的文件结构

要实现顶部Material Tabs嵌套独立底部Tabs的需求,需遵循Expo Router的路由规则,调整文件结构如下:

app/
└── toptabs/
    ├── _layout.js       # 顶部Material Tabs主布局
    ├── chat.js          # Chat顶部标签页内容
    ├── marketplace.js   # Marketplace顶部标签页内容
    └── social/
        ├── _layout.js   # Social顶部标签页内的底部Tabs布局
        ├── cats.js      # Social底部标签Cats的页面内容
        └── dogs.js      # Social底部标签Dogs的页面内容

修正后的顶部Tabs主布局(toptabs/_layout.js)

之前的错误在于直接导入了Social内部的_layout组件,打乱了Expo Router的路由解析逻辑。现在改为直接引用social目录,让Expo Router自动加载其内部的_layout作为嵌套容器:

import FontAwesome from "@expo/vector-icons/FontAwesome";
import { useColorScheme } from "react-native";
import Colors from "../../constants/Colors";
import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs";
import MarketplaceHome from "./marketplace";
import ChatHome from "./chat";
import SocialContainer from "./social";

const Tab = createMaterialTopTabNavigator();

function TabBarIcon(props: {
  name: React.ComponentProps<typeof FontAwesome>["name"];
  color: string;
}) {
  return (
    <FontAwesome
      size={28}
      style={{ marginBottom: -3 }}
      {...props}
    />
  );
}

export default function TabLayout() {
  const colorScheme = useColorScheme();

  return (
    <Tab.Navigator
      screenOptions={{
        tabBarActiveTintColor: Colors[colorScheme ?? "light"].tint,
      }}
    >
      <Tab.Screen
        name="Social"
        component={SocialContainer}
        options={{
          tabBarIcon: ({ color }) => <TabBarIcon name="home" color={color} />,
        }}
      />
      <Tab.Screen
        name="Marketplace"
        component={MarketplaceHome}
        options={{
          tabBarIcon: ({ color }) => <TabBarIcon name="feed" color={color} />,
        }}
      />
      <Tab.Screen
        name="Chat"
        component={ChatHome}
        options={{
          tabBarIcon: ({ color }) => <TabBarIcon name="female" color={color} />,
        }}
      />
    </Tab.Navigator>
  );
}

修正后的Social底部Tabs布局(social/_layout.js)

将原AppLayout重命名为_layout.js,放在social目录下,作为该目录的路由容器:

import { Tabs } from "expo-router";
import { Text } from "react-native";

export default function SocialTabsLayout() {
  return (
    <Tabs screenOptions={{ headerShown: false }}>
      <Tabs.Screen
        name="cats"
        options={{
          title: "Cats",
          tabBarIcon: () => <Text>🐱</Text>,
        }}
      />
      <Tabs.Screen
        name="dogs"
        options={{
          title: "Dogs",
          tabBarIcon: () => <Text>🐶</Text>,
        }}
      />
    </Tabs>
  );
}

补充底部标签页内容文件

需要创建cats.js和dogs.js作为底部标签的页面内容,示例如下:

// social/cats.js
import { View, Text, StyleSheet } from "react-native";

export default function CatsScreen() {
  return (
    <View style={styles.container}>
      <Text>🐱 猫咪专区</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
});
// social/dogs.js
import { View, Text, StyleSheet } from "react-native";

export default function DogsScreen() {
  return (
    <View style={styles.container}>
      <Text>🐶 狗狗专区</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
});

关键说明

  • Expo Router通过目录下的_layout.js自动识别嵌套路由,每个_layout会包裹当前目录下的所有页面
  • 顶部Material Tabs作为外层路由,每个Tab.Screen对应一个路由节点(文件或目录)
  • 仅在需要嵌套底部Tabs的顶部标签页目录下创建_layout.js并使用<Tabs>组件,避免其他顶部标签被错误识别为底部Tabs的一部分

内容的提问来源于stack exchange,提问作者Njoroge Brian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 07:35:54