or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

deep-linking.mdindex.mdlink-components.mdnavigation-container.mdnavigation-hooks.mdserver-side-rendering.mdstatic-navigation.mdtheming.md

navigation-hooks.mddocs/

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

```