Skip to main content

Stack Navigator

Stack Navigator provides a way for your app to transition between screens where each new screen is placed on top of a stack.

Comparison with Native Stack Navigator

The Stack navigator is implemented in JavaScript and mimics the familiar iOS and Android look & feel. Since it's a custom implementation, it is extremely customizable.

However, even though it runs animations and gestures with native driver, the performance may not be as good as a native implementation. This may not be an issue for many apps, but Native Stack Navigator - which uses native navigation primitives - will provide better performance and smoother animations.

In addition, because it is a custom implementation, it may not support all the features and behaviors of the underlying platforms such large titles, form sheets, etc.

Installation

To use this navigator, ensure that you have @react-navigation/native and its dependencies (follow this guide), then install @react-navigation/stack:

npm install @react-navigation/stack

The navigator depends on react-native-gesture-handler for gestures and optionally @react-native-masked-view/masked-view for UIKit style animations for the header.

If you have a Expo managed project, in your project directory, run:

npx expo install react-native-gesture-handler @react-native-masked-view/masked-view

If you're on a Mac and developing for iOS, you also need to install pods to complete the linking.

npx pod-install ios

Usage

To use this navigator, import it from @react-navigation/stack:

import {
createStackNavigator,
createStackScreen,
} from '@react-navigation/stack';

const MyStack = createStackNavigator({
screens: {
Home: createStackScreen({
screen: HomeScreen,
}),
Profile: createStackScreen({
screen: ProfileScreen,
}),
},
});

API Definition

Props

In addition to the common props shared by all navigators, the stack navigator accepts the following additional props:

detachInactiveScreens

Boolean used to indicate whether inactive screens should be detached from the view hierarchy to save memory. This enables integration with react-native-screens. Defaults to true.

If you need to disable this optimization for specific screens (e.g. you want to screen to stay in view even when unfocused) detachPreviousScreen option.

Options

The following options can be used to configure the screens in the navigator. These can be specified under screenOptions prop of Stack.Navigator or options prop of Stack.Screen.

title

String that can be used as a fallback for headerTitle.

cardShadowEnabled

Use this prop to have visible shadows during transitions. Defaults to true.

cardOverlayEnabled

Use this prop to have a semi-transparent dark overlay visible under the card during transitions. Defaults to true on Android and false on iOS.

cardOverlay

Function which returns a React Element to display as the overlay for the card. Make sure to set cardOverlayEnabled to true when using this.

cardStyle

Style object for the card in stack. You can provide a custom background color to use instead of the default background here.

You can also specify { backgroundColor: 'transparent' } to make the previous screen visible underneath (for transparent modals). This is useful to implement things like modal dialogs. You should also specify presentation: 'modal' in the options when using a transparent background so previous screens aren't detached and stay visible underneath.

On Web, the height of the screen isn't limited to the height of the viewport. This is by design to allow the browser's address bar to hide when scrolling. If this isn't desirable behavior, you can set cardStyle to { flex: 1 } to force the screen to fill the viewport.

presentation

This is shortcut option which configures several options to configure the style for rendering and transitions:

  • card: Use the default OS animations for iOS and Android screen transitions.
  • modal: Use Modal animations. This changes a few things:
    • Sets headerMode to screen for the screen unless specified otherwise.
    • Changes the screen animation to match the platform behavior for modals.
  • transparentModal: Similar to modal. This changes following things:
    • Sets headerMode to screen for the screen unless specified otherwise.
    • Sets background color of the screen to transparent, so previous screen is visible
    • Adjusts the detachPreviousScreen option so that the previous screen stays rendered.
    • Prevents the previous screen from animating from its last position.
    • Changes the screen animation to a vertical slide animation.

See Transparent modals for more details on how to customize transparentModal.

animationTypeForReplace

The type of animation to use when this screen replaces another screen. It takes the following values:

  • push - The animation of a new screen being pushed will be used
  • pop - The animation of a screen being popped will be used

Defaults to push.

When pop is used, the pop animation is applied to the screen being replaced.

gestureEnabled

Whether you can use gestures to dismiss this screen. Defaults to true on iOS, false on Android.

Gestures are not supported on Web.

gestureResponseDistance

Number to override the distance of touch start from the edge of the screen to recognize gestures.

It'll configure either the horizontal or vertical distance based on the gestureDirection value.

The default values are:

  • 50 - when gestureDirection is horizontal or horizontal-inverted
  • 135 - when gestureDirection is vertical or vertical-inverted

This is not supported on Web.

gestureVelocityImpact

Number which determines the relevance of velocity for the gesture. Defaults to 0.3.

This is not supported on Web.

gestureDirection

Direction of the gestures. Refer the Animations section for details.

This is not supported on Web.

transitionSpec

Configuration object for the screen transition. Refer the Animations section for details.

cardStyleInterpolator

Interpolated styles for various parts of the card. Refer the Animations section for details.

headerStyleInterpolator

Interpolated styles for various parts of the header. Refer the Animations section for details.

keyboardHandlingEnabled

If false, the keyboard will NOT automatically dismiss when navigating to a new screen from this screen. Defaults to true.

detachPreviousScreen

Boolean used to indicate whether to detach the previous screen from the view hierarchy to save memory. Set it to false if you need the previous screen to be seen through the active screen. Only applicable if detachInactiveScreens isn't set to false.

This is automatically adjusted when using presentation as transparentModal or modal to keep the required screens visible. Defaults to true in other cases.

freezeOnBlur

Boolean indicating whether to prevent inactive screens from re-rendering. Defaults to false. Defaults to true when enableFreeze() from react-native-screens package is run at the top of the application.

Only supported on iOS and Android.

You can find the list of header related options here. These options can be specified under screenOptions prop of Stack.Navigator or options prop of Stack.Screen. You don't have to be using @react-navigation/elements directly to use these options, they are just documented in that page.

In addition to those, the following options are also supported in stack:

Custom header to use instead of the default header.

This accepts a function that returns a React Element to display as a header. The function receives an object containing the following properties as the argument:

  • navigation - The navigation object for the current screen.
  • route - The route object for the current screen.
  • options - The options for the current screen
  • layout - Dimensions of the screen, contains height and width properties.
  • progress Animated nodes representing the progress of the animation.
  • back - Options for the back button, contains an object with a title property to use for back button label.
  • styleInterpolator - Function which returns interpolated styles for various elements in the header.

Make sure to set headerMode to screen as well when using a custom header (see below for more details).

Example:

import { getHeaderTitle } from '@react-navigation/elements';

// ..

header: ({ navigation, route, options, back }) =>