0
# Navigation Hooks
1
2
React hooks for programmatic navigation, link building, scroll management, and accessing navigation-related context information.
3
4
## Capabilities
5
6
### useLinkTo Hook
7
8
Returns a function to navigate using href-based paths.
9
10
```typescript { .api }
11
/**
12
* Helper to navigate to a screen using a href based on the linking options.
13
* Throws error if used outside NavigationContainer.
14
*/
15
function useLinkTo(): (href: string) => void;
16
```
17
18
**Usage Examples:**
19
20
```typescript
21
import { useLinkTo } from '@react-navigation/native';
22
import { Button } from 'react-native';
23
24
function NavigationButton() {
25
const linkTo = useLinkTo();
26
27
const handlePress = () => {
28
linkTo('/profile/123');
29
};
30
31
return <Button title="Go to Profile" onPress={handlePress} />;
32
}
33
34
// Navigate with query parameters
35
function SearchButton() {
36
const linkTo = useLinkTo();
37
38
const performSearch = (query: string) => {
39
linkTo(`/search?q=${encodeURIComponent(query)}`);
40
};
41
42
return (
43
<Button
44
title="Search Products"
45
onPress={() => performSearch('react navigation')}
46
/>
47
);
48
}
49
50
// Conditional navigation
51
function ConditionalNavigation() {
52
const linkTo = useLinkTo();
53
54
const navigateToProfile = () => {
55
if (userLoggedIn) {
56
linkTo('/profile');
57
} else {
58
linkTo('/login');
59
}
60
};
61
62
return <Button title="View Profile" onPress={navigateToProfile} />;
63
}
64
```
65
66
### useLinkBuilder Hook
67
68
Provides utilities for building hrefs and actions from navigation parameters.
69
70
```typescript { .api }
71
/**
72
* Helpers to build href or action based on the linking options.
73
* Returns buildHref to build an href for screen and buildAction to build an action from an href.
74
*/
75
function useLinkBuilder(): {
76
/** Build an href for a screen name and parameters */
77
buildHref: (name: string, params?: object) => string | undefined;
78
/** Build a navigation action from an href */
79
buildAction: (href: string) => NavigationAction;
80
};
81
```
82
83
**Usage Examples:**
84
85
```typescript
86
import { useLinkBuilder } from '@react-navigation/native';
87
import { Share } from 'react-native';
88
89
function ShareableScreen() {
90
const { buildHref } = useLinkBuilder();
91
92
const shareCurrentScreen = async () => {
93
const href = buildHref('CurrentScreen', { id: screenId });
94
95
if (href) {
96
await Share.share({
97
message: `Check out this screen: https://myapp.com${href}`,
98
url: `https://myapp.com${href}`,
99
});
100
}
101
};
102
103
return <Button title="Share" onPress={shareCurrentScreen} />;
104
}
105
106
// Build navigation actions
107
function CustomNavigationHandler() {
108
const { buildAction } = useLinkBuilder();
109
110
const handleDeepLink = (url: string) => {
111
try {
112
const action = buildAction(url);
113
navigation.dispatch(action);
114
} catch (error) {
115
console.error('Invalid deep link:', url);
116
}
117
};
118
119
// Used with custom URL handling logic
120
return null;
121
}
122
123
// Generate links for different screens
124
function NavigationMenu() {
125
const { buildHref } = useLinkBuilder();
126
127
const menuItems = [
128
{ name: 'Home', screen: 'Home' },
129
{ name: 'Profile', screen: 'Profile', params: { userId: currentUser.id } },
130
{ name: 'Settings', screen: 'Settings' },
131
];
132
133
return (
134
<View>
135
{menuItems.map((item) => {
136
const href = buildHref(item.screen, item.params);
137
return (
138
<TouchableOpacity
139
key={item.name}
140
onPress={() => linkTo(href)}
141
>
142
<Text>{item.name}</Text>
143
</TouchableOpacity>
144
);
145
})}
146
</View>
147
);
148
}
149
```
150
151
### useScrollToTop Hook
152
153
Automatically scrolls scrollable components to top when tab is pressed in tab navigators.
154
155
```typescript { .api }
156
/**
157
* Hook to automatically scroll to top when tab is pressed.
158
* Must be used with a ref to a scrollable component.
159
* Throws error if used outside NavigationContainer.
160
*/
161
function useScrollToTop(ref: React.RefObject<ScrollableWrapper>): void;
162
163
type ScrollableWrapper =
164
| { scrollToTop(): void }
165
| { scrollTo(options: { x?: number; y?: number; animated?: boolean }): void }
166
| { scrollToOffset(options: { offset: number; animated?: boolean }): void }
167
| { scrollResponderScrollTo(options: { x?: number; y?: number; animated?: boolean }): void }
168
| { getScrollResponder(): React.ReactNode | ScrollView }
169
| { getNode(): ScrollableWrapper }
170
| null;
171
```
172
173
**Usage Examples:**
174
175
```typescript
176
import { useScrollToTop } from '@react-navigation/native';
177
import { ScrollView, FlatList } from 'react-native';
178
179
// With ScrollView
180
function ScrollableScreen() {
181
const scrollRef = useRef<ScrollView>(null);
182
useScrollToTop(scrollRef);
183
184
return (
185
<ScrollView ref={scrollRef}>
186
{/* Your scrollable content */}
187
</ScrollView>
188
);
189
}
190
191
// With FlatList
192
function ListScreen() {
193
const listRef = useRef<FlatList>(null);
194
useScrollToTop(listRef);
195
196
return (
197
<FlatList
198
ref={listRef}
199
data={items}
200
renderItem={({ item }) => <ItemComponent item={item} />}
201
/>
202
);
203
}
204
205
// With SectionList
206
function SectionListScreen() {
207
const sectionListRef = useRef<SectionList>(null);
208
useScrollToTop(sectionListRef);
209
210
return (
211
<SectionList
212
ref={sectionListRef}
213
sections={sections}
214
renderItem={({ item }) => <ItemComponent item={item} />}
215
renderSectionHeader={({ section }) => <HeaderComponent section={section} />}
216
/>
217
);
218
}
219
220
// With custom scrollable component
221
function CustomScrollableScreen() {
222
const customScrollRef = useRef<CustomScrollComponent>(null);
223
useScrollToTop(customScrollRef);
224
225
return (
226
<CustomScrollComponent ref={customScrollRef}>
227
{/* Content */}
228
</CustomScrollComponent>
229
);
230
}
231
232
// Multiple scrollable components
233
function MultiScrollScreen() {
234
const primaryScrollRef = useRef<ScrollView>(null);
235
const secondaryScrollRef = useRef<FlatList>(null);
236
237
// Only attach to the primary scrollable component
238
useScrollToTop(primaryScrollRef);
239
240
return (
241
<View>
242
<ScrollView ref={primaryScrollRef}>
243
{/* Primary content */}
244
</ScrollView>
245
<FlatList
246
ref={secondaryScrollRef}
247
data={items}
248
renderItem={({ item }) => <Item item={item} />}
249
/>
250
</View>
251
);
252
}
253
```
254
255
### useLocale Hook
256
257
Accesses the text direction specified in the NavigationContainer.
258
259
```typescript { .api }
260
/**
261
* Hook to access the text direction specified in the NavigationContainer.
262
* Throws error if used outside NavigationContainer.
263
*/
264
function useLocale(): {
265
/** Current text direction ('ltr' or 'rtl') */
266
direction: LocaleDirection;
267
};
268
269
type LocaleDirection = 'ltr' | 'rtl';
270
```
271
272
**Usage Examples:**
273
274
```typescript
275
import { useLocale } from '@react-navigation/native';
276
import { StyleSheet, View, Text } from 'react-native';
277
278
// Basic locale-aware styling
279
function LocaleAwareComponent() {
280
const { direction } = useLocale();
281
282
return (
283
<View style={[
284
styles.container,
285
{ flexDirection: direction === 'rtl' ? 'row-reverse' : 'row' }
286
]}>
287
<Text>Content that respects text direction</Text>
288
</View>
289
);
290
}
291
292
// Conditional text alignment
293
function DirectionalText({ children }) {
294
const { direction } = useLocale();
295
296
return (
297
<Text style={[
298
styles.text,
299
{ textAlign: direction === 'rtl' ? 'right' : 'left' }
300
]}>
301
{children}
302
</Text>
303
);
304
}
305
306
// Icon positioning based on direction
307
function IconWithText({ icon, text }) {
308
const { direction } = useLocale();
309
const isRTL = direction === 'rtl';
310
311
return (
312
<View style={[
313
styles.iconContainer,
314
{ flexDirection: isRTL ? 'row-reverse' : 'row' }
315
]}>
316
<Image source={icon} style={[
317
styles.icon,
318
{ marginRight: isRTL ? 0 : 8, marginLeft: isRTL ? 8 : 0 }
319
]} />
320
<Text>{text}</Text>
321
</View>
322
);
323
}
324
325
// Animation direction
326
function SlideAnimation({ children }) {
327
const { direction } = useLocale();
328
const slideDirection = direction === 'rtl' ? 'right' : 'left';
329
330
return (
331
<Animated.View style={[
332
styles.animatedContainer,
333
getSlideStyle(slideDirection)
334
]}>
335
{children}
336
</Animated.View>
337
);
338
}
339
340
const styles = StyleSheet.create({
341
container: {
342
padding: 16,
343
},
344
text: {
345
fontSize: 16,
346
},
347
iconContainer: {
348
alignItems: 'center',
349
padding: 12,
350
},
351
icon: {
352
width: 24,
353
height: 24,
354
},
355
animatedContainer: {
356
flex: 1,
357
},
358
});
359
```
360
361
### Hook Error Handling
362
363
All navigation hooks require being used within a NavigationContainer and will throw descriptive errors when used outside the navigation context.
364
365
```typescript { .api }
366
// Error thrown when hooks are used outside NavigationContainer
367
class NavigationError extends Error {
368
message: "Couldn't find a navigation object. Is your component inside NavigationContainer?";
369
}
370
371
// Error thrown when buildAction receives invalid href
372
class LinkingError extends Error {
373
message: "The href must start with '/' (provided_href).";
374
}
375
376
// Error thrown when parsing fails
377
class StateParsingError extends Error {
378
message: "Failed to parse the href to a navigation state.";
379
}
380
```
381
382
**Error Handling Examples:**
383
384
```typescript
385
// Safe hook usage with error boundaries
386
function SafeNavigationComponent() {
387
try {
388
const linkTo = useLinkTo();
389
return <Button title="Navigate" onPress={() => linkTo('/home')} />;
390
} catch (error) {
391
console.error('Navigation hook error:', error);
392
return <Text>Navigation not available</Text>;
393
}
394
}
395
396
// Conditional hook usage
397
function ConditionalHookUsage({ hasNavigation }) {
398
if (!hasNavigation) {
399
return <Text>No navigation available</Text>;
400
}
401
402
// Hooks must still be called at the top level
403
const linkTo = useLinkTo();
404
return <Button title="Navigate" onPress={() => linkTo('/home')} />;
405
}
406
407
// Error boundary for navigation components
408
class NavigationErrorBoundary extends React.Component {
409
constructor(props) {
410
super(props);
411
this.state = { hasError: false };
412
}
413
414
static getDerivedStateFromError(error) {
415
if (error.message.includes('navigation object')) {
416
return { hasError: true };
417
}
418
return null;
419
}
420
421
render() {
422
if (this.state.hasError) {
423
return <Text>Navigation is not available in this context</Text>;
424
}
425
426
return this.props.children;
427
}
428
}
429
```