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
yarn
pnpm
bun
npm install @react-navigation/stack
yarn add @react-navigation/stack
pnpm add @react-navigation/stack
bun add @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.
- Expo
- Community CLI
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 have a bare React Native project, in your project directory, run:
npm
yarn
pnpm
bun
npm install react-native-gesture-handler @react-native-masked-view/masked-view
yarn add react-native-gesture-handler @react-native-masked-view/masked-view
pnpm add react-native-gesture-handler @react-native-masked-view/masked-view
bun add 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:
- Static
- Dynamic
import {
createStackNavigator,
createStackScreen,
} from '@react-navigation/stack';
const MyStack = createStackNavigator({
screens: {
Home: createStackScreen({
screen: HomeScreen,
}),
Profile: createStackScreen({
screen: ProfileScreen,
}),
},
});
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>
);
}
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
headerModetoscreenfor the screen unless specified otherwise. - Changes the screen animation to match the platform behavior for modals.
- Sets
transparentModal: Similar tomodal. This changes following things:- Sets
headerModetoscreenfor the screen unless specified otherwise. - Sets background color of the screen to transparent, so previous screen is visible
- Adjusts the
detachPreviousScreenoption 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.
- Sets
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 usedpop- 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- whengestureDirectionishorizontalorhorizontal-inverted135- whengestureDirectionisverticalorvertical-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.
Header related options
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:
header
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 screenlayout- Dimensions of the screen, containsheightandwidthproperties.progressAnimated nodes representing the progress of the animation.back- Options for the back button, contains an object with atitleproperty 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 }) =>