FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix: big refactor · evdeveloper/Tanstack-Router-@9bfd4f8 · GitHub

fix: big refactor · evdeveloper/Tanstack-Router-@9bfd4f8 · GitHub
Skip to content

Navigation Menu

Commit 9bfd4f8

Browse files
committed
fix: big refactor
1 parent 14160f5 commit 9bfd4f8

95 files changed

Lines changed: 2618 additions & 2351 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎docs/guide/data-loading.md‎

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -194,25 +194,26 @@ const postsLoader = new Loader({
194194
})
195195

196196
const loaderClient = new LoaderClient({
197-
getLoaders: () => ({ postsLoader }),
197+
loader: [postsLoader],
198198
})
199199

200-
// Use RootRoute's special `withRouterContext` method to require a specific type
201-
// of router context to be both available in every route and to be passed to
202-
// the router for implementation.
200+
// Create a new routerContext using new RouterContext<{...}>() class and pass it whatever types you would like to be available in your router context.
203201

204-
const rootRoute = RootRoute.withRouterContext<{
202+
const routerContext = new RouterContext<{
205203
loaderClient: typeof loaderClient
206-
}>()()
204+
}>()
205+
206+
// Then use the same routerContext to create your root route
207+
const rootRoute = routerContext.createRootRoute()
207208

208209
// Notice how our postsRoute references context to get the loader client
209210
// This can be a powerful tool for dependency injection across your router
210211
// and routes.
211212
const postsRoute = new Route({
212213
getParentPath: () => rootRoute,
213214
path: 'posts',
214-
async loader({ context }) {
215-
const { postsLoader } = context.loaderClient
215+
async loader({ context: { loaderClient } }) {
216+
const { postsLoader } = loaderClient
216217
await postsLoader.load()
217218
return () => useLoader({ loader: postsLoader })
218219
},
@@ -225,10 +226,12 @@ const postsRoute = new Route({
225226

226227
const routeTree = rootRoute.addChildren([postsRoute])
227228

229+
// Use your routerContext to create a new router
230+
// This will require that you fullfil the type requirements of the routerContext
228231
const router = new Router({
229232
routeTree,
230233
context: {
231-
// Supply our loaderClient to the whole router
234+
// Supply our loaderClient to the router (and all routes)
232235
loaderClient,
233236
},
234237
})

‎docs/guide/router-context.md‎

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ These are just suggested uses of the router context. You can use it for whatever
1515

1616
## Typed Router Context
1717

18-
Like everything else, the router context (at least the one you inject at `new Router()` is strictly typed. This type can be augemented via routes' `getContext` option. If that's the case, the type at the edge of the route is a merged interface-like type of the base context type and every route's `getContext` return type. To constrain the type of the router context, you must use the `RootRoute.withRouterContext()` factory instead of the `new RootRoute()` constructor. Here's an example:
18+
Like everything else, the router context (at least the one you inject at `new Router()` is strictly typed. This type can be augmented via any route's `getContext` option. If that's the case, the type at the edge of the route is a merged interface-like type of the base context type and every route's `getContext` return type. To constrain the type of the root router context, you must use the `new RouteContext<YourContextTypeHere>()` class to create a new `routerContext` and then use the `routerContext.createRootRoute()` method instead of the `new RootRoute()` class to create your root route. Here's an example:
1919

2020
```tsx
2121
import { RootRoute } from '@tanstack/router'
@@ -24,12 +24,22 @@ interface MyRouterContext {
2424
user: User
2525
}
2626

27-
const rootRoute = RootRoute.withRouterContext<MyRouterContext>()({
27+
const routerContext = new RouterContext<MyRouterContext>()
28+
29+
// Use the routerContext to create your root route
30+
const rootRoute = routerContext.createRootRoute({
2831
component: App,
2932
})
30-
```
3133

32-
> ⚠️ Did you notice the curried call above? Make sure you first call `RootRoute.withRouterContext<MyRouterContext>()` and then call the returned function with the route options. This is a requirement of the `RootRoute.withRouterContext` factory.
34+
const routeTree = rootRoute.addChildren([
35+
// ...
36+
])
37+
38+
// Use the routerContext to create your router
39+
const router = new Router({
40+
routeTree,
41+
})
42+
```
3343

3444
## Passing the initial Router Context
3545

@@ -40,6 +50,7 @@ The router context is passed to the router at instantiation time. You can pass t
4050
```tsx
4151
import { Router } from '@tanstack/router'
4252

53+
// Use the routerContext you created to create your router
4354
const router = new Router({
4455
routeTree,
4556
context: {
@@ -58,7 +69,7 @@ Once you have defined the router context type, you can use it in your route defi
5869
```tsx
5970
import { Route } from '@tanstack/router'
6071

61-
const userRoute = Route({
72+
const userRoute = new Route({
6273
getRootRoute: () => rootRoute,
6374
path: 'todos',
6475
component: Todos,
@@ -68,7 +79,7 @@ const userRoute = Route({
6879
})
6980
```
7081

71-
You can even inject your data fetching client itself!
82+
You can even inject your data fetching client itself... in fact, this is highly recommended!
7283

7384
```tsx
7485
import { RootRoute } from '@tanstack/router'
@@ -77,9 +88,7 @@ interface MyRouterContext {
7788
queryClient: QueryClient
7889
}
7990

80-
const rootRoute = RootRoute.withRouterContext<MyRouterContext>()({
81-
component: App,
82-
})
91+
const routerContext = new RouterContext<MyRouterContext>()
8392

8493
const queryClient = new QueryClient()
8594

@@ -96,7 +105,7 @@ Then, in your route:
96105
```tsx
97106
import { Route } from '@tanstack/router'
98107

99-
const userRoute = Route({
108+
const userRoute = new Route({
100109
getRootRoute: () => rootRoute,
101110
path: 'todos',
102111
component: Todos,
@@ -120,7 +129,9 @@ interface MyRouterContext {
120129
foo: boolean
121130
}
122131

123-
const rootRoute = RootRoute.withRouterContext<MyRouterContext>()({
132+
const routerContext = new RouterContext<MyRouterContext>()
133+
134+
const rootRoute = routerContext.createRootRoute({
124135
component: App,
125136
})
126137

@@ -131,7 +142,7 @@ const router = new Router({
131142
},
132143
})
133144

134-
const userRoute = Route({
145+
const userRoute = new Route({
135146
getRootRoute: () => rootRoute,
136147
path: 'admin',
137148
component: Todos,

‎docs/guide/ssr-and-streaming.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ export function createRouter() {
216216
// Optionally, we can use `Wrap` to wrap our router in the loader client provider
217217
Wrap: ({ children }) => {
218218
return (
219-
<LoaderClientProvider loaderClient={loaderClient}>
219+
<LoaderClientProvider client={loaderClient}>
220220
{children}
221221
</LoaderClientProvider>
222222
)

‎docs/guide/type-safety.md‎

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,13 @@ The `from` property is optional, which means if you don't pass it, you'll get th
6262

6363
Router context is so extremely useful as it's the ultimate hierarchical dependency injection. You can supply context to the router and to each and every route it renders. As you build up this context, TanStack Router will merge it down with the hierarchy of routes, so that each route has access to the context of all of its parents.
6464

65-
If you want to use context, it's highly recommended that you use the `RootRoute.withRouterContext<ContextType>()(rootRouteOptions)` utility.
66-
67-
This utility will create a requirement for you to pass a context type to your router, and will also ensure that your context is properly typed throughout the entire route tree.
65+
The `new RouteContext()` utility creates a new router context that when instantiated with a type, creates a requirement for you to fullfil the same type contract to your router, and will also ensure that your context is properly typed throughout the entire route tree.
6866

6967
```tsx
70-
const rootRoute = new RootRoute.withRouterContext<{ whateverYouWant: true }>()({
71-
component: () => {
72-
// ...
73-
},
68+
const routeContext = new RouteContext<{ whateverYouWant: true }>()
69+
70+
const rootRoute = routeContext.createRootRoute({
71+
component: App,
7472
})
7573

7674
const routeTree = rootRoute.addChildren([

‎examples/react/basic-ssr-streaming/src/entry-server.tsx‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import express from 'express'
1212
// index.js
1313
import './fetch-polyfill'
1414
import { createRouter } from './router'
15-
import { Transform } from 'stream'
1615

1716
type ReactReadableStream = ReadableStream<Uint8Array> & {
1817
allReady?: Promise<void> | undefined
@@ -34,7 +33,6 @@ export async function render(opts: {
3433
router.update({
3534
history: memoryHistory,
3635
context: {
37-
...router.context,
3836
head: opts.head,
3937
},
4038
})

‎examples/react/basic-ssr-streaming/src/index.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export function App({
3030
/>
3131
</head>
3232
<body>
33-
<LoaderClientProvider loaderClient={loaderClient}>
33+
<LoaderClientProvider client={loaderClient}>
3434
<RouterProvider router={router} />
3535
</LoaderClientProvider>
3636
</body>

‎examples/react/basic-ssr-streaming/src/loaderClient.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { postLoader } from './routes/posts/$postId'
44

55
export const createLoaderClient = () => {
66
return new LoaderClient({
7-
getLoaders: () => ({ postsLoader, postLoader, testLoader }),
7+
loaders: [postsLoader, postLoader, testLoader],
88
})
99
}
1010

‎examples/react/basic-ssr-streaming/src/router.tsx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Router } from '@tanstack/router'
1+
import { Router, RouterContext } from '@tanstack/router'
22
import { LoaderClientProvider } from '@tanstack/react-loaders'
33

44
import { rootRoute } from './routes/root'
@@ -10,10 +10,10 @@ import { postIdRoute } from './routes/posts/$postId'
1010
import { createLoaderClient } from './loaderClient'
1111
import React from 'react'
1212

13-
export type RouterContext = {
13+
export const routerContext = new RouterContext<{
1414
loaderClient: ReturnType<typeof createLoaderClient>
1515
head: string
16-
}
16+
}>()
1717

1818
export const routeTree = rootRoute.addChildren([
1919
indexRoute,
@@ -42,7 +42,7 @@ export function createRouter() {
4242
// Wrap our router in the loader client provider
4343
Wrap: ({ children }) => {
4444
return (
45-
<LoaderClientProvider loaderClient={loaderClient}>
45+
<LoaderClientProvider client={loaderClient}>
4646
{children}
4747
</LoaderClientProvider>
4848
)
@@ -55,7 +55,7 @@ export function createRouter() {
5555
hydrateLoaderInstanceFn: (instance) =>
5656
router.hydrateData(instance.hashedKey) as any,
5757
dehydrateLoaderInstanceFn: (instance) =>
58-
router.dehydrateData(instance.hashedKey, () => instance.state),
58+
router.dehydrateData(instance.hashedKey, () => instance),
5959
}
6060

6161
return router

‎examples/react/basic-ssr-streaming/src/routes/posts.tsx‎

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,17 @@
11
import * as React from 'react'
2-
import {
3-
Link,
4-
Outlet,
5-
Route,
6-
StreamedPromise,
7-
useDehydrate,
8-
useHydrate,
9-
useInjectHtml,
10-
useRouter,
11-
} from '@tanstack/router'
2+
import { Link, Outlet, Route } from '@tanstack/router'
123
import { rootRoute } from './root'
13-
// import { loaderClient } from '../entry-client'
14-
import { Loader } from '@tanstack/react-loaders'
4+
import { Loader, useLoaderInstance } from '@tanstack/react-loaders'
155
import { postIdRoute } from './posts/$postId'
166

17-
declare module 'react' {
18-
function use<T>(promise: Promise<T>): T
19-
}
20-
217
export type PostType = {
228
id: string
239
title: string
2410
body: string
2511
}
2612

2713
export const postsLoader = new Loader({
14+
key: 'posts',
2815
fn: async () => {
2916
console.log('Fetching posts...')
3017
await new Promise((r) =>
@@ -38,6 +25,7 @@ export const postsLoader = new Loader({
3825
})
3926

4027
export const testLoader = new Loader({
28+
key: 'test',
4129
fn: async (wait: number) => {
4230
await new Promise((r) => setTimeout(r, wait))
4331
return {
@@ -49,27 +37,20 @@ export const testLoader = new Loader({
4937
export const postsRoute = new Route({
5038
getParentRoute: () => rootRoute,
5139
path: 'posts',
52-
loader: async ({ context, preload }) => {
53-
const { postsLoader } = context.loaderClient.loaders
54-
await postsLoader.load({ preload })
55-
return {
56-
usePosts: () => postsLoader.useLoader(),
57-
}
40+
loader: async ({ context: { loaderClient }, preload }) => {
41+
await loaderClient.load({ key: 'posts', preload })
42+
return () => useLoaderInstance({ key: 'posts' })
5843
},
5944
component: function Posts({ useLoader }) {
60-
const { usePosts } = useLoader()
61-
62-
const {
63-
state: { data: posts },
64-
} = usePosts()
45+
const { data: posts } = useLoader()()
6546

6647
return (
6748
<div className="p-2 flex gap-2">
6849
<Test wait={1000 / 2} />
69-
<Test wait={2000 / 2} />
7050
<Test wait={3000 / 2} />
71-
<Test wait={4000 / 2} />
51+
<Test wait={2000 / 2} />
7252
<Test wait={5000 / 2} />
53+
<Test wait={4000 / 2} />
7354
<ul className="list-disc pl-4">
7455
{posts?.map((post) => {
7556
return (
@@ -104,9 +85,10 @@ function Test({ wait }: { wait: number }) {
10485
}
10586

10687
function TestInner({ wait }: { wait: number }) {
107-
const instance = testLoader.useLoader({
88+
const instance = useLoaderInstance({
89+
key: 'test',
10890
variables: wait,
10991
})
11092

111-
return <div>Test: {instance.state.data.test}</div>
93+
return <div>Test: {instance.data.test}</div>
11294
}

0 commit comments

Comments
 (0)

Footer

© 2026 GitHub, Inc.

Back | FazBrowse Home | New Git URL