离线开发tRPC与T3栈时procedure未触发问题求助
离线状态下tRPC Procedure不执行的问题解决
你的tRPC Query Procedure是运行在服务端的,离线时客户端无法和服务端建立网络连接,自然不会发起请求,服务端的console.log也就不会触发。客户端的useQuery会优先读取本地缓存(如果之前请求过),但不会触发服务端的逻辑。
解决方案1:离线时复用已有缓存
如果只是想离线时显示之前请求过的数据,给useQuery设置合适的缓存参数,让它优先用缓存而不是发起新请求:
const hello = trpc.example.hello.useQuery({ text: "World" }, { staleTime: Infinity, // 标记缓存永不过期 cacheTime: Infinity, // 缓存保留在内存的时间设为永久 });
这样离线时会直接展示之前缓存的greeting,不会显示Loading,也不会尝试发起服务端请求。
解决方案2:离线时执行本地逻辑
如果你的逻辑是纯计算(不需要服务端资源),可以把逻辑抽成共享函数,同时在服务端和前端离线场景调用:
- 抽离共享逻辑:
// utils/greeting.ts export const getGreeting = (text?: string) => { console.log("这段代码在线离线都会执行"); return { greeting: `Hello ${text ?? ""} ` }; };
- 服务端Procedure使用该函数:
// router.ts import { getGreeting } from "../utils/greeting"; export const exampleRouter = router({ hello: publicProcedure .input(z.object({ text: z.string().nullish() }).nullish()) .query(({ input }) => { return getGreeting(input?.text); }), });
- 前端离线时 fallback 到本地逻辑:
// index.tsx import { getGreeting } from "../utils/greeting"; const hello = trpc.example.hello.useQuery({ text: "World" }, { staleTime: Infinity, }); const fallbackGreeting = getGreeting("World"); return ( <> {hello.isSuccess ? ( <p>{hello.data.greeting}</p> ) : navigator.onLine ? ( <p>Loading..</p> ) : ( <p>{fallbackGreeting.greeting}</p> )} </> );
解决方案3:持久化缓存(刷新页面仍可用)
如果需要离线且刷新页面后还能显示数据,用React Query的持久化插件把缓存存在localStorage:
- 安装依赖:
npm install @tanstack/react-query-persist-client @tanstack/query-sync-storage-persister
- 配置tRPC的QueryClient:
// trpc/client.ts import { createTRPCReact } from "@trpc/react-query"; import { QueryClient } from "@tanstack/react-query"; import { persistQueryClient } from "@tanstack/react-query-persist-client"; import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister"; export const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 1000 * 60 * 5, // 缓存5分钟内视为新鲜 cacheTime: 1000 * 60 * 60, // 缓存保留1小时 }, }, }); const persister = createSyncStoragePersister({ storage: window.localStorage, }); // 持久化缓存到localStorage persistQueryClient({ queryClient, persister, });
内容的提问来源于stack exchange,提问作者John McNeill
相关产品推荐
相关产品推荐

