import {
createRootRouteWithContext,
createRouter,
} from '@tanstack/react-router'
interface MyRouterContext {
user: User
}
// Use the routerContext to create your root route
const rootRoute = createRootRouteWithContext<MyRouterContext>()({
component: App,
})
const routeTree = rootRoute.addChildren([
// ...
])
// Use the routerContext to create your router
const router = createRouter({
routeTree,
})
import { createRouter } from '@tanstack/react-router'
// Use the routerContext you created to create your router
const router = createRouter({
routeTree,
context: {
user: {
id: '123',
name: 'John Doe',
},
},
})
function useAuth() {
const router = useRouter()
const [user, setUser] = useState<User | null>(null)
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
setUser(user)
router.invalidate()
})
return unsubscribe
}, [])
return user
}
import {
createRootRouteWithContext,
createRouter,
} from '@tanstack/react-router'
interface MyRouterContext {
queryClient: QueryClient
}
const rootRoute = createRootRouteWithContext<MyRouterContext>()({
component: App,
})
const queryClient = new QueryClient()
const router = createRouter({
routeTree: rootRoute,
context: {
queryClient,
},
})
When trying to use React Context or Hooks in your route's beforeLoad or loader functions, it's important to remember React's Rules of Hooks. You can't use hooks in a non-React function, so you can't use hooks in your beforeLoad or loader functions.
So, how do we use React Context or Hooks in our route's beforeLoad or loader functions? We can use the router context to pass down the React Context or Hooks to our route's beforeLoad or loader functions.
Let's look at the setup for an example, where we pass down a useNetworkStrength hook to our route's loader function:
In this example, we'd instantiate the hook before rendering the router using the <RouterProvider />. This way, the hook would be called in React-land, therefore adhering to the Rules of Hooks.
Then, we can call the useNetworkStrength hook in our App component and pass the returned value into the router context via the <RouterProvider />:
So, now in our route's loader function, we can access the networkStrength hook from the router context:
// First, make sure the context for the root route is typed
import { createRootRouteWithContext } from '@tanstack/react-router'
import { useNetworkStrength } from '@/hooks/useNetworkStrength'
interface MyRouterContext {
networkStrength: ReturnType<typeof useNetworkStrength>
}
export const Route = createRootRouteWithContext<MyRouterContext>()({
component: App,
})
import { createRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
export const router = createRouter({
routeTree,
context: {
networkStrength: undefined!, // We'll set this in React-land
},
})
import { RouterProvider } from '@tanstack/react-router'
import { router } from './router'
import { useNetworkStrength } from '@/hooks/useNetworkStrength'
function App() {
const networkStrength = useNetworkStrength()
// Inject the returned value from the hook into the router context
return <RouterProvider router={router} context={{ networkStrength }} />
}
// ...
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/posts')({
component: Posts,
loader: ({ context }) => {
if (context.networkStrength === 'STRONG') {
// Do something
}
},
})
import { createRootRouteWithContext } from '@tanstack/react-router'
interface MyRouterContext {
foo: boolean
}
export const Route = createRootRouteWithContext<MyRouterContext>()({
component: App,
})
import { createRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
const router = createRouter({
routeTree,
context: {
foo: true,
},
})
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/todos')({
component: Todos,
beforeLoad: () => {
return {
bar: true,
}
},
loader: ({ context }) => {
context.foo // true
context.bar // true
},
})