0
# Navigation Utilities
1
2
Utility functions, hooks, and configuration objects that provide additional navigation behavior and integration capabilities. These utilities enhance the core screen functionality with platform-specific features and performance optimizations.
3
4
## Core Imports
5
6
```typescript
7
import {
8
executeNativeBackPress,
9
isSearchBarAvailableForCurrentPlatform,
10
useTransitionProgress,
11
ScreenContext,
12
compatibilityFlags,
13
featureFlags
14
} from "react-native-screens";
15
```
16
17
## Capabilities
18
19
### Native Back Press
20
21
Executes the native back press behavior on Android, which typically exits the application or navigates to the previous activity.
22
23
```typescript { .api }
24
/**
25
* Executes native back press behavior, exits the app on Android
26
* @returns Always returns true to indicate the event was handled
27
*/
28
function executeNativeBackPress(): boolean;
29
```
30
31
**Usage Example:**
32
33
```typescript
34
import { executeNativeBackPress } from "react-native-screens";
35
import { BackHandler, Platform } from "react-native";
36
37
// Custom back handler that can exit the app
38
function handleBackPress() {
39
// Perform custom logic
40
if (canExit) {
41
if (Platform.OS === 'android') {
42
return executeNativeBackPress();
43
}
44
}
45
return false; // Let default behavior handle it
46
}
47
48
// Register back handler
49
BackHandler.addEventListener('hardwareBackPress', handleBackPress);
50
```
51
52
**Platform Behavior:**
53
- **Android**: Exits the application or navigates to previous activity
54
- **iOS**: No effect (iOS doesn't have a hardware back button)
55
- **Return Value**: Always returns `true` to indicate the event was handled
56
57
### Search Bar Availability
58
59
Boolean constant indicating whether the SearchBar component is available on the current platform.
60
61
```typescript { .api }
62
/**
63
* Boolean indicating if SearchBar is available on the current platform
64
*/
65
const isSearchBarAvailableForCurrentPlatform: boolean;
66
```
67
68
**Usage Example:**
69
70
```typescript
71
import {
72
isSearchBarAvailableForCurrentPlatform,
73
SearchBar
74
} from "react-native-screens";
75
76
function ConditionalSearchScreen() {
77
return (
78
<View>
79
{isSearchBarAvailableForCurrentPlatform ? (
80
<SearchBar placeholder="Search..." />
81
) : (
82
<TextInput placeholder="Search..." />
83
)}
84
</View>
85
);
86
}
87
```
88
89
**Platform Support:**
90
- **iOS**: `true` - Native UISearchController integration
91
- **Android**: `true` - Material Design search view
92
- **Web/Other platforms**: `false` - Use fallback components
93
94
### Transition Progress Hook
95
96
Hook that provides transition progress information for native stack screens. Allows for custom animations and UI updates based on screen transition state.
97
98
```typescript { .api }
99
/**
100
* Hook that provides transition progress information for native stack screens
101
* @returns Transition progress context value with animation data
102
* @throws Error if used outside a native stack screen
103
*/
104
function useTransitionProgress(): TransitionProgressContext;
105
106
interface TransitionProgressContext {
107
/** Current transition progress (0-1) */
108
progress: Animated.Value;
109
110
/** Whether the screen is being closed (0 or 1) */
111
closing: Animated.Value;
112
113
/** Whether navigation is going forward (0 or 1) */
114
goingForward: Animated.Value;
115
}
116
```
117
118
**Usage Example:**
119
120
```typescript
121
import React from 'react';
122
import { useTransitionProgress } from "react-native-screens";
123
import { Animated } from 'react-native';
124
125
function AnimatedScreen() {
126
const { progress, closing, goingForward } = useTransitionProgress();
127
128
const scale = progress.interpolate({
129
inputRange: [0, 1],
130
outputRange: [0.8, 1],
131
});
132
133
const opacity = progress.interpolate({
134
inputRange: [0, 1],
135
outputRange: [0, 1],
136
});
137
138
return (
139
<Animated.View style={[
140
{ flex: 1 },
141
{
142
transform: [{ scale }],
143
opacity,
144
}
145
]}>
146
{/* Screen content */}
147
</Animated.View>
148
);
149
}
150
```
151
152
**Advanced Usage:**
153
154
```typescript
155
import React from 'react';
156
import { useTransitionProgress } from "react-native-screens";
157
import { Animated, View } from 'react-native';
158
159
function ComplexTransitionScreen() {
160
const { progress, closing, goingForward } = useTransitionProgress();
161
162
// Different animations for push vs pop
163
const headerTranslateY = Animated.multiply(
164
goingForward,
165
progress.interpolate({
166
inputRange: [0, 1],
167
outputRange: [-50, 0],
168
})
169
);
170
171
const contentOpacity = progress.interpolate({
172
inputRange: [0, 1],
173
outputRange: [0, 1],
174
});
175
176
return (
177
<View style={{ flex: 1 }}>
178
<Animated.View style={[
179
{ height: 60, backgroundColor: '#007AFF' },
180
{ transform: [{ translateY: headerTranslateY }] }
181
]} />
182
<Animated.View style={[
183
{ flex: 1 },
184
{ opacity: contentOpacity }
185
]}>
186
{/* Screen content */}
187
</Animated.View>
188
</View>
189
);
190
}
191
```
192
193
### Screen Context
194
195
React context that allows swapping the Screen component implementation. This is primarily used for enhanced integrations like Reanimated support.
196
197
```typescript { .api }
198
/**
199
* React context for swapping Screen component implementation
200
*/
201
const ScreenContext: React.Context<React.ComponentType<ScreenProps>>;
202
```
203
204
**Usage Example:**
205
206
```typescript
207
import React from 'react';
208
import { ScreenContext, InnerScreen } from "react-native-screens";
209
import { CustomReanimatedScreen } from './CustomReanimatedScreen';
210
211
// Provider that allows using enhanced screen implementation
212
function EnhancedScreenProvider({ children, useReanimatedScreen = false }) {
213
const ScreenImplementation = useReanimatedScreen ? CustomReanimatedScreen : InnerScreen;
214
215
return (
216
<ScreenContext.Provider value={ScreenImplementation}>
217
{children}
218
</ScreenContext.Provider>
219
);
220
}
221
222
// Consumer that uses the context
223
function ScreenConsumer(props) {
224
const ScreenWrapper = React.useContext(ScreenContext) || InnerScreen;
225
226
return <ScreenWrapper {...props} />;
227
}
228
```
229
230
**Note:** This context is primarily used internally and for advanced integrations. Most applications should use the standard `Screen` component directly.
231
232
### Compatibility Flags
233
234
Configuration object that exposes compatibility information for downstream navigation libraries to detect feature availability and maintain backward compatibility.
235
236
```typescript { .api }
237
/**
238
* Exposes compatibility information for downstream navigation libraries
239
*/
240
const compatibilityFlags: CompatibilityFlags;
241
242
interface CompatibilityFlags {
243
/** Indicates new back title implementation (v3.21+) */
244
isNewBackTitleImplementation: boolean;
245
246
/** Indicates new header implementation (v4.0+) */
247
usesHeaderFlexboxImplementation: boolean;
248
}
249
```
250
251
**Usage Example:**
252
253
```typescript
254
import { compatibilityFlags } from "react-native-screens";
255
256
// Library code that needs to handle different versions
257
function configureHeaderLayout() {
258
if (compatibilityFlags.usesHeaderFlexboxImplementation) {
259
// Use new flexbox-based header layout
260
return { flex: 1, justifyContent: 'center' };
261
} else {
262
// Use legacy header layout
263
return { position: 'absolute', top: 0, left: 0, right: 0 };
264
}
265
}
266
267
function configureBackButton() {
268
if (compatibilityFlags.isNewBackTitleImplementation) {
269
// Use new back title system
270
return { backTitle: 'Back', backTitleVisible: true };
271
} else {
272
// Use legacy back button handling
273
return { backButtonTitle: 'Back' };
274
}
275
}
276
```
277
278
### Feature Flags
279
280
Configuration object for controlling experimental and stable features globally across the application.
281
282
```typescript { .api }
283
/**
284
* Configurable global behavior flags
285
*/
286
const featureFlags: FeatureFlags;
287
288
interface FeatureFlags {
289
/** Experimental feature flags */
290
experiment: {
291
/** Experimental bottom tabs control */
292
controlledBottomTabs: boolean;
293
};
294
295
/** Stable configuration flags (currently empty) */
296
stable: {};
297
}
298
```
299
300
**Usage Example:**
301
302
```typescript
303
import { featureFlags } from "react-native-screens";
304
305
// Enable experimental bottom tabs
306
featureFlags.experiment.controlledBottomTabs = true;
307
308
// Check if experimental features are enabled
309
function useExperimentalBottomTabs() {
310
return featureFlags.experiment.controlledBottomTabs;
311
}
312
313
function ConditionalBottomTabs() {
314
if (useExperimentalBottomTabs()) {
315
return <ExperimentalBottomTabs />;
316
}
317
318
return <StandardBottomTabs />;
319
}
320
```
321
322
## Integration Patterns
323
324
### React Navigation Integration
325
326
```typescript
327
import { useTransitionProgress } from "react-native-screens";
328
import { useRoute, useNavigation } from "@react-navigation/native";
329
330
function ReactNavigationIntegration() {
331
const route = useRoute();
332
const navigation = useNavigation();
333
334
// Use transition progress for custom animations
335
const { progress } = useTransitionProgress();
336
337
// Combine with React Navigation hooks
338
const isScreenFocused = navigation.isFocused();
339
340
return (
341
<View>
342
<Text>Route: {route.name}</Text>
343
<Text>Focused: {isScreenFocused ? 'Yes' : 'No'}</Text>
344
</View>
345
);
346
}
347
```
348
349
### Custom Navigation System
350
351
```typescript
352
import {
353
executeNativeBackPress,
354
useTransitionProgress,
355
ScreenContext
356
} from "react-native-screens";
357
358
function CustomNavigationSystem({ children }) {
359
const handleBackPress = useCallback(() => {
360
// Custom back handling logic
361
if (canGoBack) {
362
goBack();
363
return true;
364
}
365
366
// Exit app on Android
367
return executeNativeBackPress();
368
}, [canGoBack, goBack]);
369
370
return (
371
<ScreenContext.Provider value={{ isActive: true, screenId: 'custom' }}>
372
{children}
373
</ScreenContext.Provider>
374
);
375
}
376
```
377
378
### Performance Monitoring
379
380
```typescript
381
import { useTransitionProgress } from "react-native-screens";
382
383
function PerformanceMonitor() {
384
const { progress } = useTransitionProgress();
385
386
useEffect(() => {
387
const listener = progress.addListener(({ value }) => {
388
// Monitor transition performance
389
console.log('Transition progress:', value);
390
391
if (value === 1) {
392
console.log('Transition completed');
393
// Log performance metrics
394
}
395
});
396
397
return () => progress.removeListener(listener);
398
}, [progress]);
399
400
return null;
401
}
402
```
403
404
## Platform-Specific Utilities
405
406
### Android Back Button Handling
407
408
```typescript
409
import { executeNativeBackPress } from "react-native-screens";
410
import { BackHandler, Platform } from "react-native";
411
412
function setupAndroidBackHandler() {
413
if (Platform.OS !== 'android') return;
414
415
const handleBackPress = () => {
416
// Custom logic before exiting
417
if (shouldExit()) {
418
executeNativeBackPress();
419
return true;
420
}
421
return false;
422
};
423
424
BackHandler.addEventListener('hardwareBackPress', handleBackPress);
425
426
return () => {
427
BackHandler.removeEventListener('hardwareBackPress', handleBackPress);
428
};
429
}
430
```
431
432
### iOS Search Integration
433
434
```typescript
435
import {
436
isSearchBarAvailableForCurrentPlatform,
437
SearchBar
438
} from "react-native-screens";
439
440
function iOSSearchIntegration() {
441
if (!isSearchBarAvailableForCurrentPlatform) {
442
return null;
443
}
444
445
return (
446
<SearchBar
447
placeholder="Search..."
448
placement="stacked"
449
hideWhenScrolling={true}
450
/>
451
);
452
}
453
```
454
455
## Error Handling
456
457
### Context Validation
458
459
```typescript
460
import { ScreenContext } from "react-native-screens";
461
462
function useScreenContext() {
463
const context = useContext(ScreenContext);
464
465
if (!context) {
466
throw new Error(
467
'useScreenContext must be used within a Screen component'
468
);
469
}
470
471
return context;
472
}
473
```
474
475
### Hook Safety
476
477
```typescript
478
import { useTransitionProgress } from "react-native-screens";
479
480
function SafeTransitionHook() {
481
try {
482
const progress = useTransitionProgress();
483
return progress;
484
} catch (error) {
485
console.warn('useTransitionProgress called outside native stack screen');
486
return null;
487
}
488
}
489
```