or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-routing.mdhistory.mdhooks.mdindex.mdlocation-context.mdnavigation.mdrouting.mdserver-rendering.mdutilities.md

hooks.mddocs/

0

# React Hooks

1

2

Modern React hooks for accessing routing state and navigation functions in functional components.

3

4

## Capabilities

5

6

### useLocation Hook

7

8

Hook to access the current location object containing path, search, hash, and state information.

9

10

```javascript { .api }

11

/**

12

* Hook to access current location object

13

* @returns Current location with pathname, search, hash, state, etc.

14

* @throws Error if used outside LocationProvider

15

*/

16

function useLocation(): Location;

17

18

interface Location {

19

pathname: string; // URI encoded/decoded

20

search: string;

21

hash: string;

22

href?: string; // Optional in non-browser environments

23

origin?: string; // Optional in non-browser environments

24

protocol?: string; // Optional in non-browser environments

25

host?: string; // Optional in non-browser environments

26

hostname?: string; // Optional in non-browser environments

27

port?: string; // Optional in non-browser environments

28

state: any;

29

key: string; // Defaults to "initial"

30

}

31

```

32

33

**Usage Examples:**

34

35

```javascript

36

import React from "react";

37

import { useLocation } from "@reach/router";

38

39

// Basic location access

40

const LocationDisplay = () => {

41

const location = useLocation();

42

43

return (

44

<div>

45

<p>Current path: {location.pathname}</p>

46

<p>Query string: {location.search}</p>

47

<p>Hash: {location.hash}</p>

48

</div>

49

);

50

};

51

52

// Conditional rendering based on location

53

const Header = () => {

54

const location = useLocation();

55

const isHomePage = location.pathname === "/";

56

57

return (

58

<header className={isHomePage ? "home-header" : "page-header"}>

59

{isHomePage ? <HeroSection /> : <PageTitle />}

60

</header>

61

);

62

};

63

64

// Accessing navigation state

65

const WelcomeMessage = () => {

66

const location = useLocation();

67

const { justLoggedIn } = location.state || {};

68

69

return (

70

<div>

71

{justLoggedIn && <p>Welcome back! You've successfully logged in.</p>}

72

</div>

73

);

74

};

75

76

// URL parameter parsing

77

const SearchResults = () => {

78

const location = useLocation();

79

const queryParams = new URLSearchParams(location.search);

80

const query = queryParams.get("q");

81

const page = parseInt(queryParams.get("page") || "1");

82

83

return (

84

<div>

85

<h1>Search Results for: {query}</h1>

86

<p>Page {page}</p>

87

</div>

88

);

89

};

90

```

91

92

### useNavigate Hook

93

94

Hook to access the navigation function for programmatic routing within components.

95

96

```javascript { .api }

97

/**

98

* Hook to access navigation function

99

* @returns Navigation function for programmatic routing

100

* @throws Error if used outside LocationProvider

101

*/

102

function useNavigate(): NavigateFunction;

103

104

interface NavigateFunction {

105

(to: string | number, options?: NavigateOptions): Promise<void>;

106

}

107

108

interface NavigateOptions {

109

state?: any;

110

replace?: boolean;

111

}

112

```

113

114

**Usage Examples:**

115

116

```javascript

117

import React from "react";

118

import { useNavigate } from "@reach/router";

119

120

// Basic programmatic navigation

121

const LoginForm = () => {

122

const navigate = useNavigate();

123

124

const handleSubmit = async (formData) => {

125

const success = await login(formData);

126

if (success) {

127

navigate("/dashboard");

128

}

129

};

130

131

return <form onSubmit={handleSubmit}>{/* form content */}</form>;

132

};

133

134

// Navigation with state

135

const ProductCreator = () => {

136

const navigate = useNavigate();

137

138

const handleCreate = async (productData) => {

139

const newProduct = await createProduct(productData);

140

navigate(`/products/${newProduct.id}`, {

141

state: { justCreated: true, product: newProduct }

142

});

143

};

144

145

return <ProductForm onSubmit={handleCreate} />;

146

};

147

148

// History navigation

149

const NavigationControls = () => {

150

const navigate = useNavigate();

151

152

return (

153

<div>

154

<button onClick={() => navigate(-1)}>Back</button>

155

<button onClick={() => navigate(1)}>Forward</button>

156

<button onClick={() => navigate("/")}>Home</button>

157

</div>

158

);

159

};

160

161

// Conditional navigation with replace

162

const RedirectHandler = ({ shouldRedirect, redirectTo }) => {

163

const navigate = useNavigate();

164

165

React.useEffect(() => {

166

if (shouldRedirect) {

167

navigate(redirectTo, { replace: true });

168

}

169

}, [shouldRedirect, redirectTo, navigate]);

170

171

return null;

172

};

173

```

174

175

### useParams Hook

176

177

Hook to access route parameters from the current matched route.

178

179

```javascript { .api }

180

/**

181

* Hook to access route parameters from current matched route

182

* Matches parameters against the current base path context

183

* @returns Object with route parameters or null if no match

184

* @throws Error if used outside Router

185

*/

186

function useParams(): Record<string, string | string[]> | null;

187

```

188

189

**Usage Examples:**

190

191

```javascript

192

import React from "react";

193

import { useParams } from "@reach/router";

194

195

// Basic parameter access

196

const UserProfile = () => {

197

const params = useParams();

198

const { userId } = params || {};

199

200

if (!userId) {

201

return <div>No user specified</div>;

202

}

203

204

return <div>User ID: {userId}</div>;

205

};

206

207

// Multiple parameters

208

const BlogPost = () => {

209

const params = useParams();

210

const { category, postId } = params || {};

211

212

return (

213

<article>

214

<p>Category: {category}</p>

215

<p>Post ID: {postId}</p>

216

</article>

217

);

218

};

219

220

// Parameter validation and effects

221

const ProductDetails = () => {

222

const params = useParams();

223

const { productId } = params || {};

224

const [product, setProduct] = React.useState(null);

225

const [loading, setLoading] = React.useState(true);

226

227

React.useEffect(() => {

228

if (productId) {

229

setLoading(true);

230

fetchProduct(productId)

231

.then(setProduct)

232

.finally(() => setLoading(false));

233

}

234

}, [productId]);

235

236

if (!productId) {

237

return <div>Product not found</div>;

238

}

239

240

if (loading) {

241

return <div>Loading...</div>;

242

}

243

244

return <div>Product: {product?.name}</div>;

245

};

246

247

// Using with wildcard parameters

248

const FileViewer = () => {

249

const params = useParams();

250

const filepath = params["*"]; // or params.filepath if named wildcard

251

252

return (

253

<div>

254

<h1>File Viewer</h1>

255

<p>File path: {filepath}</p>

256

</div>

257

);

258

};

259

```

260

261

### useMatch Hook

262

263

Hook to check if a specific path matches the current location and get match details.

264

265

```javascript { .api }

266

/**

267

* Hook to check if a path matches current location

268

* @param path - Path pattern to match against

269

* @returns Match result with params and uri, or null if no match

270

* @throws Error if used outside Router or if path is not provided

271

*/

272

function useMatch(path: string): MatchResult | null;

273

274

interface MatchResult {

275

uri: string; // Always normalized with leading slash

276

path: string;

277

[paramName: string]: string | string[]; // Can contain arrays for splat routes

278

}

279

```

280

281

**Usage Examples:**

282

283

```javascript

284

import React from "react";

285

import { useMatch } from "@reach/router";

286

287

// Basic path matching

288

const ConditionalComponent = () => {

289

const match = useMatch("/admin/*");

290

291

if (match) {

292

return <AdminToolbar />;

293

}

294

295

return null;

296

};

297

298

// Match with parameters

299

const UserContextProvider = ({ children }) => {

300

const userMatch = useMatch("/users/:userId/*");

301

const userId = userMatch?.userId;

302

303

return (

304

<UserContext.Provider value={{ userId }}>

305

{children}

306

</UserContext.Provider>

307

);

308

};

309

310

// Multiple matches for complex logic

311

const PageLayout = ({ children }) => {

312

const dashboardMatch = useMatch("/dashboard/*");

313

const adminMatch = useMatch("/admin/*");

314

const publicMatch = useMatch("/public/*");

315

316

let layoutClass = "default-layout";

317

if (dashboardMatch) layoutClass = "dashboard-layout";

318

else if (adminMatch) layoutClass = "admin-layout";

319

else if (publicMatch) layoutClass = "public-layout";

320

321

return (

322

<div className={layoutClass}>

323

{dashboardMatch && <DashboardSidebar />}

324

{adminMatch && <AdminHeader />}

325

<main>{children}</main>

326

</div>

327

);

328

};

329

330

// Dynamic styling based on match

331

const NavigationItem = ({ path, children }) => {

332

const match = useMatch(path);

333

334

return (

335

<li className={match ? "nav-item active" : "nav-item"}>

336

{children}

337

</li>

338

);

339

};

340

341

// Accessing match details

342

const BreadcrumbTrail = () => {

343

const productMatch = useMatch("/products/:productId");

344

const categoryMatch = useMatch("/categories/:categoryId");

345

346

const breadcrumbs = [];

347

348

if (categoryMatch) {

349

breadcrumbs.push({

350

label: `Category ${categoryMatch.categoryId}`,

351

path: `/categories/${categoryMatch.categoryId}`

352

});

353

}

354

355

if (productMatch) {

356

breadcrumbs.push({

357

label: `Product ${productMatch.productId}`,

358

path: `/products/${productMatch.productId}`

359

});

360

}

361

362

return (

363

<nav>

364

{breadcrumbs.map((crumb, index) => (

365

<span key={index}>

366

<Link to={crumb.path}>{crumb.label}</Link>

367

{index < breadcrumbs.length - 1 && " > "}

368

</span>

369

))}

370

</nav>

371

);

372

};

373

```

374

375

### Hook Usage Requirements

376

377

All hooks must be used within the appropriate context providers.

378

379

```javascript { .api }

380

/**

381

* Hook usage requirements:

382

* - useLocation and useNavigate require LocationProvider or Router

383

* - useParams and useMatch require Router

384

* - All hooks follow standard React hooks rules

385

*/

386

```

387

388

**Usage Examples:**

389

390

```javascript

391

// Correct usage - hooks inside providers

392

const App = () => (

393

<Router>

394

<UserProfile path="/users/:userId" />

395

</Router>

396

);

397

398

const UserProfile = () => {

399

const params = useParams(); // ✓ Inside Router

400

const location = useLocation(); // ✓ Inside Router (which provides LocationProvider)

401

const navigate = useNavigate(); // ✓ Inside Router

402

const match = useMatch("/users/:userId/settings"); // ✓ Inside Router

403

404

return <div>User: {params.userId}</div>;

405

};

406

407

// Error handling for missing context

408

const SafeComponent = () => {

409

try {

410

const location = useLocation();

411

return <div>Path: {location.pathname}</div>;

412

} catch (error) {

413

return <div>Component must be used within a Router</div>;

414

}

415

};

416

417

// Custom hook combining multiple routing hooks

418

const useRouteInfo = () => {

419

const location = useLocation();

420

const params = useParams();

421

const navigate = useNavigate();

422

423

return {

424

location,

425

params,

426

navigate,

427

isHomePage: location.pathname === "/",

428

queryParams: new URLSearchParams(location.search)

429

};

430

};

431

```