Tanstack Router:如何将自定义上下文值传入beforeLoad处理器
解决Tanstack Router中beforeLoad访问更新后自定义上下文的问题
问题原因
Tanstack Router的初始上下文会在TSRouteProvider首次挂载时传入,但当自定义App上下文(比如user、signedIn)更新时,路由上下文不会自动同步——因为路由实例的上下文状态不会主动监听React组件状态变化,必须手动触发更新。
解决方案
通过Tanstack Router提供的setRouterContext方法,在自定义上下文更新时手动同步路由上下文的值。
步骤1:修改RouteProvider组件
在RouteProvider中监听App上下文的变化,一旦user或signedIn更新,调用setRouterContext更新路由上下文:
import { RouterProvider as TSRouteProvider } from '@tanstack/react-router'; // 假设你的router是全局导出的实例 import { router } from './path/to/your/router'; ... const RouteProvider: FC = () => { const { user, signedIn, loaded } = useApp(); // 监听上下文变化,同步路由上下文 useEffect(() => { if (loaded) { router.setRouterContext({ user, signedIn }); } }, [user, signedIn, loaded]); if (!loaded) { return null; } // 初始挂载时传入上下文 return <TSRouteProvider router={router} context={{ user, signedIn }} />; }; export default RouteProvider;
如果你的router是通过useRouter钩子获取的(比如在组件内创建),可以替换为:
import { RouterProvider as TSRouteProvider, useRouter } from '@tanstack/react-router'; ... const RouteProvider: FC = () => { const { user, signedIn, loaded } = useApp(); const router = useRouter(); useEffect(() => { if (loaded) { router.setRouterContext({ user, signedIn }); } }, [user, signedIn, loaded, router]); if (!loaded) { return null; } return <TSRouteProvider router={router} context={{ user, signedIn }} />; };
步骤2:在beforeLoad中访问最新上下文
现在你可以在路由的beforeLoad处理器中直接获取更新后的上下文值:
import { createFileRoute } from '@tanstack/react-router'; export const Route = createFileRoute('/protected-route')({ beforeLoad: async ({ context }) => { // 这里能拿到最新的signedIn和user值 if (!context.signedIn) { return { redirect: '/login' }; } console.log('当前用户:', context.user); }, });
注意事项
- 确保在调用
setRouterContext时loaded为true,避免在上下文未初始化时传入无效值。 - 如果路由上下文需要更多字段,只需在
setRouterContext中扩展传入的对象即可。
内容的提问来源于stack exchange,提问作者oliakaoil
相关产品推荐
相关产品推荐

