0
# Screen Configuration
1
2
Screen-level configuration options including animations, lazy loading, headers, and behavior control for optimizing performance and user experience in bottom tab navigation.
3
4
## Capabilities
5
6
### Screen Loading Behavior
7
8
Control when and how screens are loaded and rendered.
9
10
```typescript { .api }
11
interface ScreenLoadingOptions {
12
/**
13
* Whether this screen should render the first time it's accessed. Defaults to `true`.
14
* Set it to `false` if you want to render the screen on initial render.
15
*/
16
lazy?: boolean;
17
18
/**
19
* Whether inactive screens should be suspended from re-rendering. Defaults to `false`.
20
* Defaults to `true` when `enableFreeze()` is run at the top of the application.
21
* Requires `react-native-screens` version >=3.16.0.
22
* Only supported on iOS and Android.
23
*/
24
freezeOnBlur?: boolean;
25
}
26
```
27
28
**Usage Examples:**
29
30
```typescript
31
<Tab.Screen
32
name="ExpensiveScreen"
33
component={ExpensiveScreen}
34
options={{
35
lazy: true, // Only load when first accessed
36
freezeOnBlur: true, // Suspend when not active
37
}}
38
/>
39
40
// Load immediately for important screens
41
<Tab.Screen
42
name="Dashboard"
43
component={DashboardScreen}
44
options={{
45
lazy: false, // Load on app start
46
}}
47
/>
48
```
49
50
### Screen Navigation Behavior
51
52
Configure how screens behave during navigation and focus changes.
53
54
```typescript { .api }
55
interface ScreenNavigationBehavior {
56
/**
57
* Whether any nested stack should be popped to top when navigating away from the tab.
58
* Defaults to `false`.
59
*/
60
popToTopOnBlur?: boolean;
61
}
62
```
63
64
**Usage Examples:**
65
66
```typescript
67
<Tab.Screen
68
name="UserProfile"
69
component={UserProfileNavigator}
70
options={{
71
popToTopOnBlur: true, // Reset nested navigation when leaving tab
72
}}
73
/>
74
```
75
76
### Screen Animations
77
78
Configure custom animations for screen transitions when switching tabs.
79
80
```typescript { .api }
81
interface ScreenAnimationOptions {
82
/**
83
* How the screen should animate when switching tabs.
84
* Supported values:
85
* - 'none': don't animate the screen (default)
86
* - 'fade': cross-fade the screens.
87
* - 'shift': screens slightly shift to left/right.
88
*/
89
animation?: TabAnimationName;
90
91
/**
92
* Function which specifies interpolated styles for bottom-tab scenes.
93
*/
94
sceneStyleInterpolator?: BottomTabSceneStyleInterpolator;
95
96
/**
97
* Object which specifies the animation type (timing or spring) and their options.
98
*/
99
transitionSpec?: TransitionSpec;
100
}
101
102
type TabAnimationName = 'none' | 'fade' | 'shift';
103
104
type BottomTabSceneStyleInterpolator = (
105
props: BottomTabSceneInterpolationProps
106
) => BottomTabSceneInterpolatedStyle;
107
108
type TransitionSpec =
109
| {
110
animation: 'timing';
111
config: Omit<
112
Animated.TimingAnimationConfig,
113
'toValue' | keyof Animated.AnimationConfig
114
>;
115
}
116
| {
117
animation: 'spring';
118
config: Omit<
119
Animated.SpringAnimationConfig,
120
'toValue' | keyof Animated.AnimationConfig
121
>;
122
};
123
```
124
125
**Usage Examples:**
126
127
```typescript
128
import { SceneStyleInterpolators, TransitionSpecs } from '@react-navigation/bottom-tabs';
129
130
<Tab.Screen
131
name="AnimatedScreen"
132
component={AnimatedScreen}
133
options={{
134
animation: 'fade',
135
sceneStyleInterpolator: SceneStyleInterpolators.forFade,
136
transitionSpec: TransitionSpecs.FadeSpec,
137
}}
138
/>
139
140
// Custom animation
141
<Tab.Screen
142
name="CustomAnimated"
143
component={CustomScreen}
144
options={{
145
animation: 'shift',
146
sceneStyleInterpolator: ({ current }) => ({
147
sceneStyle: {
148
opacity: current.progress.interpolate({
149
inputRange: [-1, 0, 1],
150
outputRange: [0, 1, 0],
151
}),
152
transform: [
153
{
154
scale: current.progress.interpolate({
155
inputRange: [-1, 0, 1],
156
outputRange: [0.85, 1, 0.85],
157
}),
158
},
159
],
160
},
161
}),
162
transitionSpec: {
163
animation: 'spring',
164
config: {
165
stiffness: 1000,
166
damping: 500,
167
mass: 3,
168
},
169
},
170
}}
171
/>
172
```
173
174
### Screen Styling
175
176
Control the visual appearance of individual screens.
177
178
```typescript { .api }
179
interface ScreenStylingOptions {
180
/**
181
* Style object for the component wrapping the screen content.
182
*/
183
sceneStyle?: StyleProp<ViewStyle>;
184
}
185
```
186
187
**Usage Examples:**
188
189
```typescript
190
<Tab.Screen
191
name="ThemedScreen"
192
component={ThemedScreen}
193
options={{
194
sceneStyle: {
195
backgroundColor: '#f5f5f5',
196
paddingTop: 20,
197
},
198
}}
199
/>
200
```
201
202
### Screen Headers
203
204
Configure headers for individual screens within the tab navigator.
205
206
```typescript { .api }
207
interface ScreenHeaderOptions {
208
/**
209
* Function that returns a React Element to display as a header.
210
*/
211
header?: (props: BottomTabHeaderProps) => React.ReactNode;
212
213
/**
214
* Whether to show the header. Setting this to `false` hides the header.
215
* Defaults to `true`.
216
*/
217
headerShown?: boolean;
218
219
/**
220
* Title text for the screen.
221
*/
222
title?: string;
223
}
224
225
interface BottomTabHeaderProps {
226
/**
227
* Layout of the screen.
228
*/
229
layout: Layout;
230
/**
231
* Options for the current screen.
232
*/
233
options: BottomTabNavigationOptions;
234
/**
235
* Route object for the current screen.
236
*/
237
route: RouteProp<ParamListBase>;
238
/**
239
* Navigation prop for the header.
240
*/
241
navigation: BottomTabNavigationProp<ParamListBase>;
242
}
243
```
244
245
**Usage Examples:**
246
247
```typescript
248
<Tab.Screen
249
name="Profile"
250
component={ProfileScreen}
251
options={{
252
title: 'User Profile',
253
headerShown: true,
254
header: ({ navigation, route, options }) => (
255
<CustomHeader
256
title={options.title}
257
onBackPress={() => navigation.goBack()}
258
/>
259
),
260
}}
261
/>
262
263
// Hide header for specific screen
264
<Tab.Screen
265
name="FullScreen"
266
component={FullScreenScreen}
267
options={{
268
headerShown: false,
269
}}
270
/>
271
```
272
273
## Animation Interpolation Props
274
275
For custom scene style interpolators, you have access to animation progress values.
276
277
```typescript { .api }
278
interface BottomTabSceneInterpolationProps {
279
/**
280
* Values for the current screen.
281
*/
282
current: {
283
/**
284
* Animated value for the current screen:
285
* - -1 if the index is lower than active tab,
286
* - 0 if they're active,
287
* - 1 if the index is higher than active tab
288
*/
289
progress: Animated.Value;
290
};
291
}
292
293
interface BottomTabSceneInterpolatedStyle {
294
/**
295
* Interpolated style for the view representing the scene containing screen content.
296
*/
297
sceneStyle: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
298
}
299
```
300
301
**Usage Examples:**
302
303
```typescript
304
const customInterpolator = ({ current }) => ({
305
sceneStyle: {
306
opacity: current.progress.interpolate({
307
inputRange: [-1, 0, 1],
308
outputRange: [0, 1, 0],
309
}),
310
transform: [
311
{
312
translateX: current.progress.interpolate({
313
inputRange: [-1, 0, 1],
314
outputRange: [-100, 0, 100],
315
}),
316
},
317
{
318
rotateY: current.progress.interpolate({
319
inputRange: [-1, 0, 1],
320
outputRange: ['-45deg', '0deg', '45deg'],
321
}),
322
},
323
],
324
},
325
});
326
```
327
328
## Screen Listeners
329
330
Handle navigation events at the screen level.
331
332
```typescript { .api }
333
interface BottomTabNavigationListeners {
334
tabPress?: (e: EventArg<'tabPress', true, undefined>) => void;
335
tabLongPress?: (e: EventArg<'tabLongPress', false, undefined>) => void;
336
transitionStart?: (e: EventArg<'transitionStart', false, undefined>) => void;
337
transitionEnd?: (e: EventArg<'transitionEnd', false, undefined>) => void;
338
focus?: (e: EventArg<'focus', false, undefined>) => void;
339
blur?: (e: EventArg<'blur', false, undefined>) => void;
340
}
341
```
342
343
**Usage Examples:**
344
345
```typescript
346
<Tab.Screen
347
name="Analytics"
348
component={AnalyticsScreen}
349
listeners={{
350
tabPress: (e) => {
351
// Track tab press analytics
352
analytics.track('tab_pressed', { tab: 'Analytics' });
353
},
354
focus: () => {
355
// Refresh data when screen comes into focus
356
refreshAnalyticsData();
357
},
358
blur: () => {
359
// Cleanup or save state when leaving screen
360
saveCurrentState();
361
},
362
}}
363
/>
364
```
365
366
## Dynamic Screen Options
367
368
Configure screen options based on navigation state, route parameters, or theme.
369
370
```typescript { .api }
371
interface BottomTabOptionsArgs<
372
ParamList extends ParamListBase,
373
RouteName extends keyof ParamList = keyof ParamList,
374
NavigatorID extends string | undefined = undefined
375
> extends BottomTabScreenProps<ParamList, RouteName, NavigatorID> {
376
theme: Theme;
377
}
378
379
type ScreenOptionsFunction = (
380
args: BottomTabOptionsArgs
381
) => BottomTabNavigationOptions;
382
```
383
384
**Usage Examples:**
385
386
```typescript
387
<Tab.Screen
388
name="Settings"
389
component={SettingsScreen}
390
options={({ route, navigation, theme }) => ({
391
title: route.params?.section ? `${route.params.section} Settings` : 'Settings',
392
sceneStyle: {
393
backgroundColor: theme.colors.background,
394
},
395
tabBarBadge: route.params?.hasUpdates ? '!' : undefined,
396
headerShown: route.params?.hideHeader !== true,
397
})}
398
/>
399
```