npm-tanstack--react-router

Description
Modern and scalable routing for React applications with built-in data fetching, caching, and state management capabilities
Author
tessl
Last updated

How to use

npx @tessl/cli registry install tessl/npm-tanstack--react-router@1.132.0

react-hooks.md docs/

1
# React Hooks
2
3
React hooks for accessing router state, navigation functions, route data, parameters, and managing router interactions. These hooks provide type-safe access to all router functionality.
4
5
## Capabilities
6
7
### Router Access Hooks
8
9
Hooks for accessing the router instance and router state.
10
11
```typescript { .api }
12
/**
13
* Access the router instance
14
* @param opts - Options for router access
15
* @returns Router instance
16
*/
17
function useRouter<TRouter extends AnyRouter = RegisteredRouter>(
18
opts?: { warn?: boolean }
19
): TRouter;
20
21
/**
22
* Subscribe to router state changes
23
* @param opts - Router state subscription options
24
* @returns Selected router state
25
*/
26
function useRouterState<
27
TRouter extends AnyRouter = RegisteredRouter,
28
TSelected = RouterState<TRouter>,
29
TStructuralSharing extends boolean = true
30
>(
31
opts?: {
32
router?: TRouter;
33
select?: (state: RouterState<TRouter>) => TSelected;
34
structuralSharing?: TStructuralSharing;
35
}
36
): UseRouterStateResult<TRouter, TSelected>;
37
```
38
39
**Usage Examples:**
40
41
```typescript
42
import { useRouter, useRouterState } from "@tanstack/react-router";
43
44
function MyComponent() {
45
// Access router instance
46
const router = useRouter();
47
48
// Subscribe to loading state
49
const isLoading = useRouterState({
50
select: (state) => state.isLoading,
51
});
52
53
// Subscribe to current location
54
const location = useRouterState({
55
select: (state) => state.location,
56
});
57
58
return (
59
<div>
60
Current path: {location.pathname}
61
{isLoading && <div>Loading...</div>}
62
</div>
63
);
64
}
65
```
66
67
### Navigation Hooks
68
69
Hooks for programmatic navigation and location access.
70
71
```typescript { .api }
72
/**
73
* Get navigation function for programmatic navigation
74
* @param defaultOpts - Default navigation options
75
* @returns Type-safe navigation function
76
*/
77
function useNavigate<
78
TRouter extends AnyRouter = RegisteredRouter,
79
TDefaultFrom extends RoutePaths<TRouter> = "/"
80
>(
81
defaultOpts?: { from?: TDefaultFrom }
82
): UseNavigateResult<TRouter, TDefaultFrom>;
83
84
/**
85
* Access current location with optional selection
86
* @param opts - Location access options
87
* @returns Current location or selected subset
88
*/
89
function useLocation<
90
TRouter extends AnyRouter = RegisteredRouter,
91
TSelected = ParsedLocation,
92
TStructuralSharing extends boolean = true
93
>(
94
opts?: {
95
select?: (location: ParsedLocation) => TSelected;
96
structuralSharing?: TStructuralSharing;
97
}
98
): UseLocationResult<TSelected>;
99
100
/**
101
* Check if browser can navigate back
102
* @returns Whether back navigation is possible
103
*/
104
function useCanGoBack(): boolean;
105
```
106
107
**Usage Examples:**
108
109
```typescript
110
import { useNavigate, useLocation, useCanGoBack } from "@tanstack/react-router";
111
112
function NavigationComponent() {
113
const navigate = useNavigate();
114
const location = useLocation();
115
const canGoBack = useCanGoBack();
116
117
// Navigate programmatically
118
const handleNavigate = () => {
119
navigate({
120
to: "/posts/$postId",
121
params: { postId: "123" },
122
search: { tab: "comments" },
123
});
124
};
125
126
// Navigate with state
127
const handleNavigateWithState = () => {
128
navigate({
129
to: "/profile",
130
state: { fromDashboard: true },
131
replace: true,
132
});
133
};
134
135
return (
136
<div>
137
<p>Current path: {location.pathname}</p>
138
<button onClick={handleNavigate}>Go to Post</button>
139
<button onClick={() => navigate({ to: -1 })} disabled={!canGoBack}>
140
Go Back
141
</button>
142
</div>
143
);
144
}
145
```
146
147
### Route Data Hooks
148
149
Hooks for accessing route-specific data, parameters, and search values.
150
151
```typescript { .api }
152
/**
153
* Access route parameters with type safety
154
* @param opts - Params access options
155
* @returns Route parameters or selected subset
156
*/
157
function useParams<
158
TRouter extends AnyRouter = RegisteredRouter,
159
TFrom extends RoutePaths<TRouter> = "/",
160
TStrict extends boolean = true,
161
TThrow extends boolean = true,
162
TSelected = ResolveParams<TRouter, TFrom>,
163
TStructuralSharing extends boolean = true
164
>(
165
opts?: {
166
from?: TFrom;
167
strict?: TStrict;
168
shouldThrow?: TThrow;
169
select?: (params: ResolveParams<TRouter, TFrom>) => TSelected;
170
structuralSharing?: TStructuralSharing;
171
}
172
): UseParamsResult<TRouter, TFrom, TStrict, TThrow, TSelected>;
173
174
/**
175
* Access search parameters with type safety
176
* @param opts - Search access options
177
* @returns Search parameters or selected subset
178
*/
179
function useSearch<
180
TRouter extends AnyRouter = RegisteredRouter,
181
TFrom extends RoutePaths<TRouter> = "/",
182
TStrict extends boolean = true,
183
TThrow extends boolean = true,
184
TSelected = InferFullSearchSchema<TRouter, TFrom>,
185
TStructuralSharing extends boolean = true
186
>(
187
opts?: {
188
from?: TFrom;
189
strict?: TStrict;
190
shouldThrow?: TThrow;
191
select?: (search: InferFullSearchSchema<TRouter, TFrom>) => TSelected;
192
structuralSharing?: TStructuralSharing;
193
}
194
): UseSearchResult<TRouter, TFrom, TStrict, TThrow, TSelected>;
195
196
/**
197
* Access loader data from route
198
* @param opts - Loader data access options
199
* @returns Loader data or selected subset
200
*/
201
function useLoaderData<
202
TRouter extends AnyRouter = RegisteredRouter,
203
TFrom extends RoutePaths<TRouter> = "/",
204
TStrict extends boolean = true,
205
TSelected = ResolveLoaderData<TRouter, TFrom>,
206
TStructuralSharing extends boolean = true
207
>(
208
opts?: {
209
from?: TFrom;
210
strict?: TStrict;
211
select?: (data: ResolveLoaderData<TRouter, TFrom>) => TSelected;
212
structuralSharing?: TStructuralSharing;
213
}
214
): UseLoaderDataResult<TRouter, TFrom, TStrict, TSelected>;
215
216
/**
217
* Access loader dependencies
218
* @param opts - Loader deps access options
219
* @returns Loader dependencies
220
*/
221
function useLoaderDeps<
222
TRouter extends AnyRouter = RegisteredRouter,
223
TFrom extends RoutePaths<TRouter> = "/",
224
TStrict extends boolean = true,
225
TSelected = ResolveLoaderDeps<TRouter, TFrom>,
226
TStructuralSharing extends boolean = true
227
>(
228
opts?: {
229
from?: TFrom;
230
strict?: TStrict;
231
select?: (deps: ResolveLoaderDeps<TRouter, TFrom>) => TSelected;
232
structuralSharing?: TStructuralSharing;
233
}
234
): UseLoaderDepsResult<TRouter, TFrom, TStrict, TSelected>;
235
236
/**
237
* Access route context
238
* @param opts - Route context access options
239
* @returns Route context or selected subset
240
*/
241
function useRouteContext<
242
TRouter extends AnyRouter = RegisteredRouter,
243
TFrom extends RoutePaths<TRouter> = "/",
244
TStrict extends boolean = true,
245
TSelected = RouteContext<TRouter, TFrom>,
246
TStructuralSharing extends boolean = true
247
>(
248
opts?: {
249
from?: TFrom;
250
strict?: TStrict;
251
select?: (context: RouteContext<TRouter, TFrom>) => TSelected;
252
structuralSharing?: TStructuralSharing;
253
}
254
): UseRouteContextResult<TRouter, TFrom, TStrict, TSelected>;
255
```
256
257
**Usage Examples:**
258
259
```typescript
260
import { useParams, useSearch, useLoaderData, useRouteContext } from "@tanstack/react-router";
261
262
function PostDetail() {
263
// Access route parameters
264
const { postId } = useParams({ from: "/posts/$postId" });
265
266
// Access search parameters with selection
267
const page = useSearch({
268
from: "/posts/$postId",
269
select: (search) => search.page || 1,
270
});
271
272
// Access loader data
273
const { post, comments } = useLoaderData({ from: "/posts/$postId" });
274
275
// Access route context
276
const user = useRouteContext({
277
select: (context) => context.user,
278
});
279
280
return (
281
<div>
282
<h1>{post.title}</h1>
283
<p>Post ID: {postId}</p>
284
<p>Page: {page}</p>
285
<p>Viewing as: {user.name}</p>
286
</div>
287
);
288
}
289
```
290
291
### Route Match Hooks
292
293
Hooks for accessing route matches and match-related functionality.
294
295
```typescript { .api }
296
/**
297
* Access route match data
298
* @param opts - Match access options
299
* @returns Route match or selected subset
300
*/
301
function useMatch<
302
TRouter extends AnyRouter = RegisteredRouter,
303
TFrom extends RoutePaths<TRouter> = "/",
304
TStrict extends boolean = true,
305
TThrow extends boolean = true,
306
TSelected = RouteMatch<TRouter, TFrom>,
307
TStructuralSharing extends boolean = true
308
>(
309
opts?: {
310
from?: TFrom;
311
strict?: TStrict;
312
shouldThrow?: TThrow;
313
select?: (match: RouteMatch<TRouter, TFrom>) => TSelected;
314
structuralSharing?: TStructuralSharing;
315
}
316
): UseMatchResult<TRouter, TFrom, TStrict, TThrow, TSelected>;
317
318
/**
319
* Access all active route matches
320
* @param opts - Matches access options
321
* @returns Array of route matches or selected subset
322
*/
323
function useMatches<
324
TRouter extends AnyRouter = RegisteredRouter,
325
TSelected = RouteMatch[],
326
TStructuralSharing extends boolean = true
327
>(
328
opts?: {
329
select?: (matches: RouteMatch[]) => TSelected;
330
structuralSharing?: TStructuralSharing;
331
}
332
): UseMatchesResult<TSelected>;
333
334
/**
335
* Access parent matches relative to current match
336
* @param opts - Parent matches access options
337
* @returns Array of parent matches or selected subset
338
*/
339
function useParentMatches<
340
TRouter extends AnyRouter = RegisteredRouter,
341
TSelected = RouteMatch[],
342
TStructuralSharing extends boolean = true
343
>(
344
opts?: {
345
select?: (matches: RouteMatch[]) => TSelected;
346
structuralSharing?: TStructuralSharing;
347
}
348
): UseMatchesResult<TSelected>;
349
350
/**
351
* Access child matches relative to current match
352
* @param opts - Child matches access options
353
* @returns Array of child matches or selected subset
354
*/
355
function useChildMatches<
356
TRouter extends AnyRouter = RegisteredRouter,
357
TSelected = RouteMatch[],
358
TStructuralSharing extends boolean = true
359
>(
360
opts?: {
361
select?: (matches: RouteMatch[]) => TSelected;
362
structuralSharing?: TStructuralSharing;
363
}
364
): UseMatchesResult<TSelected>;
365
366
/**
367
* Get function to check if routes match current location
368
* @returns Function that returns match params or false
369
*/
370
function useMatchRoute<TRouter extends AnyRouter = RegisteredRouter>(): (
371
opts: UseMatchRouteOptions<TRouter>
372
) => false | AllParams<TRouter>;
373
```
374
375
**Usage Examples:**
376
377
```typescript
378
import { useMatch, useMatches, useParentMatches, useMatchRoute } from "@tanstack/react-router";
379
380
function RouteInfo() {
381
// Access current match
382
const match = useMatch();
383
384
// Access all matches with breadcrumb info
385
const breadcrumbs = useMatches({
386
select: (matches) => matches.map(match => ({
387
id: match.id,
388
pathname: match.pathname,
389
title: match.context?.title || match.routeId,
390
})),
391
});
392
393
// Access parent matches
394
const parentMatches = useParentMatches();
395
396
// Check route matching
397
const matchRoute = useMatchRoute();
398
const isOnProfile = matchRoute({ to: "/profile" });
399
400
return (
401
<div>
402
<nav>
403
{breadcrumbs.map((crumb) => (
404
<span key={crumb.id}>{crumb.title} / </span>
405
))}
406
</nav>
407
<p>Current match: {match.routeId}</p>
408
<p>Parent matches: {parentMatches.length}</p>
409
{isOnProfile && <p>Currently on profile page</p>}
410
</div>
411
);
412
}
413
```
414
415
### Navigation Blocking Hooks
416
417
Hooks for blocking navigation based on conditions.
418
419
```typescript { .api }
420
/**
421
* Block navigation conditionally
422
* @param opts - Navigation blocking options
423
* @returns Blocker resolver if using resolver pattern
424
*/
425
function useBlocker<
426
TRouter extends AnyRouter = RegisteredRouter,
427
TWithResolver extends boolean = false
428
>(
429
opts: {
430
shouldBlockFn: ShouldBlockFn;
431
enableBeforeUnload?: boolean | (() => boolean);
432
disabled?: boolean;
433
withResolver?: TWithResolver;
434
}
435
): TWithResolver extends true ? BlockerResolver : void;
436
437
type ShouldBlockFn = (
438
fromLocation: ParsedLocation,
439
toLocation: ParsedLocation
440
) => boolean;
441
442
interface BlockerResolver {
443
status: "idle" | "blocked";
444
confirm: () => void;
445
cancel: () => void;
446
}
447
```
448
449
**Usage Examples:**
450
451
```typescript
452
import { useBlocker } from "@tanstack/react-router";
453
454
function FormWithUnsavedChanges() {
455
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
456
457
// Block navigation if there are unsaved changes
458
useBlocker({
459
shouldBlockFn: () => hasUnsavedChanges,
460
enableBeforeUnload: true,
461
});
462
463
// With resolver pattern
464
const blocker = useBlocker({
465
shouldBlockFn: () => hasUnsavedChanges,
466
withResolver: true,
467
});
468
469
return (
470
<form>
471
<input onChange={() => setHasUnsavedChanges(true)} />
472
473
{blocker.status === "blocked" && (
474
<div>
475
<p>You have unsaved changes. Are you sure you want to leave?</p>
476
<button onClick={blocker.confirm}>Yes, leave</button>
477
<button onClick={blocker.cancel}>Stay</button>
478
</div>
479
)}
480
</form>
481
);
482
}
483
```
484
485
### Async Data Hooks
486
487
Hooks for handling deferred promises and async data.
488
489
```typescript { .api }
490
/**
491
* Handle deferred promises with suspense
492
* @param options - Await options
493
* @returns Tuple of resolved data and promise state
494
*/
495
function useAwaited<T>(
496
options: AwaitOptions<T>
497
): [T, DeferredPromise<T>];
498
499
interface AwaitOptions<T> {
500
/** Promise to await */
501
promise: Promise<T>;
502
}
503
504
interface DeferredPromise<T> extends Promise<T> {
505
__deferredState: DeferredPromiseState<T>;
506
}
507
508
interface DeferredPromiseState<T> {
509
status: "pending" | "success" | "error";
510
data?: T;
511
error?: any;
512
}
513
```
514
515
**Usage Examples:**
516
517
```typescript
518
import { useAwaited, defer } from "@tanstack/react-router";
519
520
function AsyncDataComponent() {
521
const { deferredPosts } = useLoaderData();
522
523
try {
524
const [posts, promise] = useAwaited({ promise: deferredPosts });
525
526
return (
527
<div>
528
<h2>Posts (Status: {promise.__deferredState.status})</h2>
529
{posts.map(post => (
530
<div key={post.id}>{post.title}</div>
531
))}
532
</div>
533
);
534
} catch (promise) {
535
// This will suspend until the promise resolves
536
throw promise;
537
}
538
}
539
```
540
541
### Link Props Hook
542
543
Hook for getting link element props with all link logic applied.
544
545
```typescript { .api }
546
/**
547
* Get props for link elements with all link logic
548
* @param options - Link options
549
* @param forwardedRef - Optional forwarded ref
550
* @returns Props object for anchor element
551
*/
552
function useLinkProps<
553
TRouter extends AnyRouter = RegisteredRouter,
554
TFrom extends string = string,
555
TTo extends string | undefined = undefined,
556
TMaskFrom extends string = TFrom,
557
TMaskTo extends string = ""
558
>(
559
options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,
560
forwardedRef?: React.ForwardedRef<Element>
561
): React.ComponentPropsWithRef<"a">;
562
563
interface UseLinkPropsOptions<TRouter extends AnyRouter, TFrom extends string, TTo extends string | undefined, TMaskFrom extends string, TMaskTo extends string>
564
extends LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> {
565
/** Disabled state */
566
disabled?: boolean;
567
}
568
```
569
570
**Usage Examples:**
571
572
```typescript
573
import { useLinkProps } from "@tanstack/react-router";
574
575
function CustomLink({ to, children, ...props }) {
576
const linkProps = useLinkProps({
577
to,
578
activeProps: { className: "active" },
579
preload: "intent",
580
...props,
581
});
582
583
return (
584
<a {...linkProps} className={`custom-link ${linkProps.className || ""}`}>
585
{children}
586
</a>
587
);
588
}
589
```
590
591
### Utility Hooks
592
593
Utility hooks for common React patterns and DOM interactions.
594
595
```typescript { .api }
596
/**
597
* Hook for accessing previous values across renders
598
* @param value - Current value
599
* @returns Previous value or null if no previous value
600
*/
601
function usePrevious<T>(value: T): T | null;
602
603
/**
604
* Hook for stable callback references that don't cause re-renders
605
* @param fn - Function to stabilize
606
* @returns Stable function reference
607
*/
608
function useStableCallback<T extends (...args: Array<any>) => any>(fn: T): T;
609
610
/**
611
* Hook for working with forwarded refs
612
* @param ref - Forwarded ref from React.forwardRef
613
* @returns Inner ref that can be used on DOM elements
614
*/
615
function useForwardedRef<T>(ref?: React.ForwardedRef<T>): React.RefObject<T>;
616
617
/**
618
* Hook for IntersectionObserver functionality
619
* @param ref - Ref to element to observe
620
* @param callback - Callback when intersection changes
621
* @param intersectionObserverOptions - IntersectionObserver options
622
* @param options - Hook-specific options
623
*/
624
function useIntersectionObserver<T extends Element>(
625
ref: React.RefObject<T | null>,
626
callback: (entry: IntersectionObserverEntry | undefined) => void,
627
intersectionObserverOptions?: IntersectionObserverInit,
628
options?: { disabled?: boolean }
629
): void;
630
631
/**
632
* Hook for custom element scroll restoration
633
* @param options - Scroll restoration configuration
634
* @returns Scroll restoration entry if available
635
*/
636
function useElementScrollRestoration(
637
options: (
638
| {
639
id: string;
640
getElement?: () => Window | Element | undefined | null;
641
}
642
| {
643
id?: string;
644
getElement: () => Window | Element | undefined | null;
645
}
646
) & {
647
getKey?: (location: ParsedLocation) => string;
648
}
649
): ScrollRestorationEntry | undefined;
650
```
651
652
**Usage Examples:**
653
654
```typescript
655
import {
656
usePrevious,
657
useStableCallback,
658
useForwardedRef,
659
useIntersectionObserver,
660
useElementScrollRestoration,
661
} from "@tanstack/react-router";
662
663
// Previous value tracking
664
function CounterComponent({ count }: { count: number }) {
665
const prevCount = usePrevious(count);
666
667
return (
668
<div>
669
Current: {count}, Previous: {prevCount}
670
</div>
671
);
672
}
673
674
// Stable callbacks to prevent re-renders
675
function ExpensiveComponent({ onUpdate }: { onUpdate: (data: any) => void }) {
676
const stableOnUpdate = useStableCallback(onUpdate);
677
678
// This won't cause child re-renders when onUpdate reference changes
679
return <ChildComponent onUpdate={stableOnUpdate} />;
680
}
681
682
// Forwarded refs
683
const CustomInput = React.forwardRef<HTMLInputElement>((props, ref) => {
684
const innerRef = useForwardedRef(ref);
685
686
return <input ref={innerRef} {...props} />;
687
});
688
689
// Intersection observer
690
function LazyImage({ src, alt }: { src: string; alt: string }) {
691
const [isVisible, setIsVisible] = useState(false);
692
const imgRef = useRef<HTMLImageElement>(null);
693
694
useIntersectionObserver(
695
imgRef,
696
(entry) => {
697
if (entry?.isIntersecting) {
698
setIsVisible(true);
699
}
700
},
701
{ rootMargin: "100px" }
702
);
703
704
return (
705
<img
706
ref={imgRef}
707
src={isVisible ? src : undefined}
708
alt={alt}
709
/>
710
);
711
}
712
713
// Element scroll restoration
714
function CustomScrollableComponent() {
715
const containerRef = useRef<HTMLDivElement>(null);
716
717
const scrollEntry = useElementScrollRestoration({
718
id: "custom-scrollable",
719
getElement: () => containerRef.current,
720
});
721
722
useEffect(() => {
723
if (scrollEntry && containerRef.current) {
724
containerRef.current.scrollTop = scrollEntry.scrollY;
725
}
726
}, [scrollEntry]);
727
728
return <div ref={containerRef}>...</div>;
729
}
730
```
731
732
## Types
733
734
### Hook Result Types
735
736
```typescript { .api }
737
type UseNavigateResult<TRouter extends AnyRouter, TDefaultFrom extends RoutePaths<TRouter>> =
738
<TTo extends RoutePaths<TRouter> = "/", TFrom extends RoutePaths<TRouter> = TDefaultFrom>(
739
options: NavigateOptions<TRouter, TFrom, TTo>
740
) => Promise<void>;
741
742
type UseLocationResult<TSelected> = TSelected extends ParsedLocation
743
? ParsedLocation
744
: TSelected;
745
746
type UseParamsResult<TRouter extends AnyRouter, TFrom extends RoutePaths<TRouter>, TStrict extends boolean, TThrow extends boolean, TSelected> =
747
TStrict extends false
748
? TThrow extends false
749
? TSelected | undefined
750
: TSelected
751
: TSelected;
752
753
type UseSearchResult<TRouter extends AnyRouter, TFrom extends RoutePaths<TRouter>, TStrict extends boolean, TThrow extends boolean, TSelected> =
754
TStrict extends false
755
? TThrow extends false
756
? TSelected | undefined
757
: TSelected
758
: TSelected;
759
760
type UseMatchesResult<TSelected> = TSelected;
761
```
762
763
### Hook Options Types
764
765
```typescript { .api }
766
interface UseMatchRouteOptions<TRouter extends AnyRouter = AnyRouter> {
767
to: RoutePaths<TRouter>;
768
params?: Record<string, any>;
769
search?: Record<string, any>;
770
hash?: string;
771
fuzzy?: boolean;
772
includeSearch?: boolean;
773
includeHash?: boolean;
774
}
775
```