Stack Navigator:什么是堆栈导航器,React Native 中的堆栈导航

作者: IT Sectr 发布日期: 2026-02-22 阅读时间: 11 分钟

Stack Navigator — React Navigation 库的组件,用于按堆栈(LIFO)原则管理移动应用的屏幕。每个新屏幕都放置在前一个屏幕之上,「返回」按钮移除顶部屏幕并将用户返回到前一个屏幕。有关导航架构的更多信息,请阅读 React Navigation 官方文档

要点

  • Stack Navigator — React Navigation 组件,用于按堆栈(LIFO)原则管理屏幕
  • 堆栈导航 — 每个屏幕都放置在前一个屏幕之上;「返回」按钮移除当前屏幕
  • Native Stack — 通过 UINavigationController(iOS)和 Fragment(Android)的原生实现
  • 动画 — 内置过渡(slide、fade、none)和通过 cardStyleInterpolator 的自定义动画
  • TypeScript — 通过 RootStackParamList 对导航参数进行完整类型化

什么是 Stack Navigator?

Stack Navigator — React Navigation 库的基础导航器之一,实现了屏幕的堆栈模型。它为移动用户提供了熟悉的导航方式:新屏幕打开时伴随从右侧进入的动画,「返回」按钮或滑动手势将用户返回到上一个屏幕。Stack Navigator 在 iOS 和 Android 上均受支持,使用平台的原生组件以获得最佳性能。

React Navigation 是 React Native 最流行的导航库,安装在 85% 的项目中(根据 npm 数据,2026 年)。Stack Navigator 是其核心的一部分,有两种实现方式:createNativeStackNavigator(原生,推荐)和 createStackNavigator(JavaScript,用于复杂的自定义动画)。原生版本出现在 React Navigation v5 中,并成为 v6+ 的标准。

Stack Navigator 的主要优势 — 自然的行为,iOS 和 Android 用户都很熟悉。在 iOS 上,堆栈在视觉上表示为 UINavigationController,在 Android 上 — 表示为具有 slide 动画的 FragmentManager。开发人员无需手动实现堆栈逻辑 — 导航器自动管理屏幕状态、back stack 和动画。

堆栈导航的工作原理

堆栈导航基于 LIFO(后进先出)原则。当用户打开新屏幕时,导航器将其放置在堆栈顶部。按下「返回」时,顶部屏幕被移除,用户看到上一个屏幕。堆栈可以包含任意数量的屏幕 — 限制仅受设备内存影响。

堆栈中的每个屏幕都保持其状态。返回上一个屏幕时,其状态会自动恢复。这使堆栈不同于其他导航类型(Tab、Drawer),在这些类型中屏幕可能会被重新创建。React Navigation 通过其自身的导航上下文机制管理状态。

操作结果示例
navigate将屏幕放置在堆栈顶部navigation.navigate('Profile')
goBack从堆栈中移除顶部屏幕navigation.goBack()
push强制添加新屏幕navigation.push('Profile')
popToTop返回到根屏幕navigation.popToTop()
reset用新集合替换整个堆栈navigation.reset({ index: 0, routes: [...] })

返回的滑动手势

在 iOS 上,Stack Navigator 支持从屏幕左边缘滑动返回的手势 — 这是用户期望的标准 iOS 行为。在 Android 上,该手势默认禁用,但可以通过 gestureEnabled 选项启用。在 Native Stack 中,该手势原生工作,没有 JavaScript 线程延迟。

Native Stack 对比 JS Stack

React Navigation 提供两种类型的 Stack Navigator:Native Stack(createNativeStackNavigator)和 JS Stack(createStackNavigator)。主要区别在于动画执行的位置。Native Stack 使用 iOS 和 Android 的原生动画驱动,而 JS Stack 通过 React Native 的 JavaScript 线程工作。它们之间的选择取决于性能和自定义需求。

Native Stack 推荐用于大多数项目。它提供流畅的 60 FPS 动画而不阻塞 JS 线程,在 iOS 上支持系统滑动手势,并使用原生过渡 — iOS 上为 slide,Android 上为 fade。然而,Native Stack 在动画自定义方面有限制:只有预定义的过渡集可用。

JS Stack 通过 cardStyleInterpolator 提供对动画的完全控制。开发人员可以创建任何动画:缩放、旋转、视差、自定义曲线。缺点 — 动画在 JS 线程中运行,在复杂过渡时可能在弱设备上导致帧率下降。对于 70% 的项目,Native Stack 完全足够。

typescript
// Native Stack — 推荐实现
import { createNativeStackNavigator } from '@react-navigation/native-stack';

type RootStackParamList = {
  Home: undefined;
  Profile: { userId: string; name: string };
  Settings: undefined;
};

const Stack = createNativeStackNavigator<RootStackParamList>();

function AppNavigator() {
  return (
    <Stack.Navigator screenOptions={{ headerShown: true }}>
      <Stack.Screen name="Home" component={HomeScreen} />
      <Stack.Screen name="Profile" component={ProfileScreen} />
      <Stack.Screen name="Settings" component={SettingsScreen} />
    </Stack.Navigator>
  );
}

安装和配置 Stack Navigator

要开始使用 Stack Navigator,需要安装 React Navigation 及其依赖项。最小集合包括 @react-navigation/native、@react-navigation/native-stack 和 react-native-screens。安装后,应用程序被包裹在 NavigationContainer 中 — 一个为所有子组件提供导航状态的上下文。

bash
# 安装 React Navigation 依赖
npm install @react-navigation/native @react-navigation/native-stack
npm install react-native-screens react-native-safe-area-context

# 对于 iOS — 安装 pod
cd ios && pod install && cd ..

安装后,创建 Stack.Navigator,其中在 RootStackParamList 中定义了屏幕。每个屏幕通过 component prop 与 React 组件连接。导航器可以是根导航器或嵌套在其他导航器(Tab、Drawer)中。配置使用 screenOptions — 对所有屏幕通用或对每个屏幕单独设置。

typescript
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

type RootStackParamList = {
  Home: undefined;
  Details: { itemId: number; title: string };
};

const Stack = createNativeStackNavigator<RootStackParamList>();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home"
        screenOptions={{
          headerStyle: { backgroundColor: '#6200ee' },
          headerTintColor: '#fff',
          gestureEnabled: true,
        }}>
        <Stack.Screen name="Home" component={HomeScreen}
          options={{ title: '主页' }} />
        <Stack.Screen name="Details" component={DetailsScreen}
          options={({ route }) => ({ title: route.params.title })} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

Stack Navigator 的参数和自定义

Stack Navigator 提供许多选项来定制外观和行为。主要参数通过 Navigator 级别的 screenOptions 或 Screen 级别的 options 设置。开发人员可以配置标题、过渡动画、滑动手势、卡片样式和背景变暗。设置的灵活性允许将导航调整为应用程序的设计系统。

选项类型描述
headerShownboolean显示或隐藏屏幕标题
headerStyleobject标题面板样式(backgroundColor, elevation)
headerBackTitlestring「返回」按钮文本(iOS)
gestureEnabledboolean启用返回的滑动手势
animationstring动画类型:slide_from_right, fade, none
contentStyleobject屏幕内部区域样式

通过 cardStyleInterpolator 自定义动画

对于 JS Stack,cardStyleInterpolator 允许在屏幕之间创建任意过渡动画。这是实现独特视觉效果的有力工具:缩放、旋转、视差、水平翻转。该函数接收动画的当前进度值(current、next)并返回动画元素的样式。

使用 TypeScript 进行导航类型化

Stack Navigator 支持通过 TypeScript 进行完整的类型化。为此,定义 RootStackParamList — 一个类型对象,其中键是屏幕名称,值是参数类型。类型化后,navigation.navigate 和 route.params 获得自动完成和类型检查。这消除了在编译阶段传递参数的错误。

typescript
type RootStackParamList = {
  Home: undefined;
  Product: { id: string; category: string };
  Checkout: { items: CartItem[]; total: number };
};

// 类型化屏幕
type ProductScreenProps = NativeStackScreenProps<RootStackParamList, 'Product'>;

function ProductScreen({ navigation, route }: ProductScreenProps) {
  const { id, category } = route.params;

  return (
    <View>
      <Text>商品 {id} — {category}</Text>
      <Button title="加入购物车"
        onPress={() => navigation.navigate('Checkout', {
          items: [{ id, quantity: 1 }],
          total: 99.99,
        })} />
    </View>
  );
}

高级场景:模态窗口和组

Stack Navigator 支持屏幕分组和模态窗口。组(Screen Group)允许将公共设置应用于多个屏幕而无需重复。模态窗口通过 stack presentation: 'modal' 实现 — 屏幕从底部打开并背景变暗,类似于 iOS 上的系统模态。此选项仅在 Native Stack 中可用。

对于复杂导航,Stack Navigator 可以嵌套在 Tab Navigator 或 Drawer Navigator 中。例如,「主页」标签包含自己的屏幕堆栈,「个人资料」标签包含自己的。这种导航器的组合是生产应用的标准方法。每个堆栈是独立的:一个标签内的 back stack 不会影响其他标签。

typescript
// Tab Navigator 中的嵌套堆栈
const HomeStack = createNativeStackNavigator<HomeStackParamList>();

function HomeStackScreen() {
  return (
    <HomeStack.Navigator>
      <HomeStack.Screen name="Feed" component={FeedScreen} />
      <HomeStack.Screen name="PostDetail" component={PostDetailScreen}
        options={{ presentation: 'modal' }} />
    </HomeStack.Navigator>
  );
}

// 具有共享选项的屏幕组
<Stack.Navigator>
  <Stack.Group screenOptions={{ headerShown: true }}>
    <Stack.Screen name="Main" component={MainScreen} />
    <Stack.Screen name="About" component={AboutScreen} />
  </Stack.Group>
  <Stack.Screen name="Auth" component={AuthScreen}
    options={{ presentation: 'modal', headerShown: false }} />
</Stack.Navigator>

常见问题

Stack Navigator 中 navigate 和 push 有什么区别?

navigate 首先在堆栈中查找具有该名称的现有屏幕,如果找到则导航到该屏幕。push 始终在堆栈顶部添加新屏幕,即使类似屏幕已经存在。当需要用不同数据打开同一屏幕时(例如用户个人资料),push 很有用。

如何在 Stack Navigator 中向屏幕传递参数?

参数作为 navigate 方法的第二个参数传递:navigation.navigate('Profile', { userId: '123', name: 'John' })。在接收屏幕上,参数可通过 route.params 访问。参数类型在 RootStackParamList 中定义,以便在 TypeScript 中自动完成。

Stack Navigator 还是 Tab Navigator — 如何选择?

Stack Navigator 适用于线性导航(屏幕 → 详情 → 编辑)。Tab Navigator — 适用于应用的平行部分(主页、搜索、个人资料)。在生产项目中,它们会结合使用:Tab Navigator 为每个标签包含多个 Stack Navigator。

Stack Navigator 中的「返回」按钮如何工作?

默认情况下,Stack Navigator 会为除根屏幕外的所有屏幕在标题中添加「返回」按钮。在 iOS 上,从左边缘滑动的手势也起作用。navigation.goBack() 方法从堆栈中移除当前屏幕并将用户返回到上一个屏幕。

能否完全自定义 Stack Navigator 中的动画?

Native Stack 中,预定义的动画可用:slide_from_right、fade、none。要完全自定义,使用带有 cardStyleInterpolator 的 JS Stack — 一个在动画每一帧返回卡片样式的函数。这允许创建任何过渡:缩放、视差、3D 旋转。

总结

  • Stack Navigator — React Navigation 组件,用于按 LIFO 原则管理屏幕,具有原生性能
  • Native Stack(createNativeStackNavigator)使用 iOS 和 Android 的原生动画,推荐用于 85% 的项目
  • RootStackParamList 在 TypeScript 中提供导航参数的完整类型化
  • Screen options 允许配置每个屏幕的标题、动画、手势和样式
  • 组和模态 — 用于组织相关屏幕和模态窗口的内置机制
  • 导航器组合 — Stack Navigator 嵌套在 Tab/Drawer 中用于生产架构
  • JS Stack 通过 cardStyleInterpolator 提供对动画的完全控制,实现独特过渡

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读