资讯动态

Preact Query 的 QueryClientProviderProps 类型详解:从 Props 到上下文注入的完整原理

发布时间:2026/9/10 14:30:39 来源:尧图企业网站定制
Preact Query 的 QueryClientProviderProps 类型详解从 Props 到上下文注入的完整原理【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/queryQueryClientProviderProps 是 tanstack/preact-query 中定义 QueryClientProvider 组件所接受全部属性的类型别名它决定了数据缓存实例QueryClient如何在 Preact 组件树中自上而下地传播。本文以该类型定义为骨架结合仓库源码与测试用例系统讲解client、children两个属性的语义、Provider 的生命周期挂载逻辑、useQueryClient读取机制以及多实例缓存隔离等实战要点。类型定义只有两个属性的精简 Props在仓库中QueryClientProviderProps定义于 packages/preact-query/src/QueryClientProvider.tsx:38类型原文如下type QueryClientProviderProps object展开后的完整结构为export type QueryClientProviderProps { /** * **Required** * * The QueryClient instance to provide. */ client: QueryClient /** * The components that get access to the provided QueryClient. */ children?: ComponentChildren }整个类型只有两个成员一个必填的client一个可选的children。这与 React Query、Solid Query 等兄弟包中 Provider 的设计保持一致的抽象组件本身不携带任何查询配置只负责把一个已构建好的QueryClient实例注入到上下文再由子树中的 hooks 读取。属性逐一拆解client必填类型QueryClient必填性Required语义要向下提供的QueryClient实例。该实例封装了QueryCache、MutationCache、默认选项以及mount/unmount等核心能力是 Preact Query 应用的数据中枢。QueryClient来自 tanstack/query-core可在构造时注入自定义缓存与默认选项例如import { QueryClient, QueryClientProvider } from tanstack/preact-query // 传入自定义 QueryCache const queryClient new QueryClient({ queryCache: myQueryCache })实践中client通常通过new QueryClient()在组件树之外创建一次并确保它是稳定引用见下文“Provider 的挂载副作用”。children可选类型ComponentChildren必填性可选语义所有能够通过useQueryClient读取到该QueryClient的组件。ComponentChildren是 Preact 的通用子节点类型涵盖元素、片段、字符串、数组以及函数式子组件等。Provider 的挂载副作用mount/unmount 生命周期从源码可见QueryClientProvider本身只是薄薄一层封装QueryClientProvider.tsx:70export const QueryClientProvider ({ client, children, }: QueryClientProviderProps): VNode { useEffect(() { client.mount() return () { client.unmount() } }, [client]) return ( QueryClientContext.Provider value{client} {children} /QueryClientContext.Provider ) }它的行为可以概括为三点注入上下文通过QueryClientContext.Provider把client交给所有子树组件读取挂载订阅组件挂载时调用client.mount()将客户端订阅到焦点focus与在线online事件卸载清理组件卸载时调用client.unmount()取消订阅恢复副作用。QueryClientContext正是useQueryClient读取的上下文对象定义于 QueryClientProvider.tsx:9export const QueryClientContext createContextQueryClient | undefined( undefined, )mount/unmount 在 query-core 中的真实行为mount()与unmount()的底层实现在 packages/query-core/src/queryClient.ts:80mount(): void { this.#mountCount if (this.#mountCount ! 1) return this.#unsubscribeFocus focusManager.subscribe(async (focused) { if (focused) { await this.resumePausedMutations() this.#queryCache.onFocus() } }) this.#unsubscribeOnline onlineManager.subscribe(async (online) { if (online) { await this.resumePausedMutations() this.#queryCache.onOnline() } }) } unmount(): void { this.#mountCount-- if (this.#mountCount ! 0) return // 退订 focus / online 订阅 }从中可以提炼出两个关键结论焦点恢复自动重新拉取当浏览器窗口重新获得焦点focused为真时客户端会先恢复被暂停的网络相关 mutation再触发queryCache.onFocus()让受影响的查询按需重新请求这正是 Preact Query “窗口聚焦自动重取”能力的来源与 docs/framework/preact/guides/window-focus-refetching.md 指南相互印证上线自动恢复网络从离线切换为在线时同样先恢复暂停的 mutation再执行queryCache.onOnline()引用计数保护mount/unmount使用mountCount计数只有第一个挂载的 Provider 真正建立订阅最后一个卸载的 Provider 才真正退订——这保证同一个QueryClient被多个 Provider 包裹时不会重复订阅或提前释放。这也解释了为何 Provider 的useEffect依赖数组是[client]若应用不小心在渲染中重建QueryClient新的引用会触发先 unmount 再 mount导致不必要的订阅抖动因此始终建议把QueryClient提升为稳定的模块级或顶层单例。useQueryClient读取上下文的标准入口useQueryClient与 Provider 定义在同一个文件中QueryClientProvider.tsx:21是从“Provider 提供的 client”到“组件拿到 client”的桥梁export const useQueryClient (queryClient?: QueryClient) { const client useContext(QueryClientContext) if (queryClient) { return queryClient } if (!client) { throw new Error(No QueryClient set, use QueryClientProvider to set one) } return client }支持显式传入queryClient参数直接返回便于调用方脱离上下文使用自定义实例未传参时读取最近上下文中的QueryClient若组件树中不存在 Provider会抛出No QueryClient set, use QueryClientProvider to set one错误。对应的类型说明文档可见 docs/framework/preact/reference/functions/useQueryClient.md上下文对象的语义说明见 docs/framework/preact/reference/variables/QueryClientContext.md。最小可用示例组装一个完整应用把以上内容串起来一个完整的最小示例在 docs/framework/preact/reference/functions/QueryClientProvider.md 中给出import { QueryClient, QueryClientProvider } from tanstack/preact-query const queryClient new QueryClient() function App() { return QueryClientProvider client{queryClient}.../QueryClientProvider }其中client{queryClient}正是QueryClientProviderProps的必填字段...处是children即应用中所有使用useQuery、useMutation、useQueryClient等的组件。例如一个带请求的子组件import { useQuery } from tanstack/preact-query function Page() { const { data } useQuery({ queryKey: [greeting], queryFn: () fetch(/api/greeting).then((r) r.text()), }) return h1{data}/h1 }当整个组件树都被 Provider 包裹后Page内部的useQuery会自动经由查询观察者访问 Provider 提供的QueryClient及其缓存。缓存分区多个 Provider 并存的实际用例因为每个QueryClient都持有独立的QueryCache在同一个应用中嵌套或并列多个QueryClientProvider就能把缓存划分到不同区域。仓库测试 packages/preact-query/src/tests/QueryClientProvider.test.tsx:53 专门验证了这种“多个缓存分区”场景const queryClient1 new QueryClient({ queryCache: queryCache1 }) const queryClient2 new QueryClient({ queryCache: queryCache2 }) render( QueryClientProvider client{queryClient1} Page1 / /QueryClientProvider QueryClientProvider client{queryClient2} Page2 / /QueryClientProvider /, )断言结果证明Page1的数据只落入queryCache1Page2的数据只落入queryCache2两个缓存互不污染queryCache1.find({ queryKey: key2 })返回undefined。这一特性适合需要多租户隔离或独立缓存区域的应用。同一测试文件还印证了另外两点Provider 提供统一缓存测试 QueryClientProvider.test.tsx:22 证明子树内所有查询共用 Provider 传入的QueryCachedefaultOptions 生效测试 QueryClientProvider.test.tsx:109 证明在new QueryClient({ defaultOptions: { queries: { gcTime: Infinity } } })后子树查询未显式配置时也会继承该默认gcTime。常见错误与规避建议综合源码行为实际使用时有几条经验法则必须用 Provider 包裹再调用 hooks未包裹就调用useQueryClient()会直接抛错测试 QueryClientProvider.test.tsx:148 中expect(() render(Page /)).toThrow(No QueryClient set...)已覆盖该路径在组件外创建并复用 client避免在组件体内new QueryClient()导致每次渲染传入新引用触发[client]依赖下的反复 mount/unmount同一个 client 可以被多个 Provider 包裹由于mountCount引用计数机制不会产生重复订阅适合 Provider 拆分场景。导出与关联入口QueryClientProvider、QueryClientContext、useQueryClient以及类型QueryClientProviderProps统一从包的入口文件导出packages/preact-query/src/index.ts:33因此使用者只需一行导入即可获得全部相关能力import { QueryClientProvider, QueryClientContext, useQueryClient, } from tanstack/preact-query import type { QueryClientProviderProps } from tanstack/preact-query查阅官方参考文档可对照组件说明见 docs/framework/preact/reference/functions/QueryClientProvider.md类型整体索引见 docs/framework/preact/reference/type-aliases/QueryClientProviderProps.md。综上QueryClientProviderProps虽仅含两个字段却是理解 Preact Query 数据流入口、缓存生命周期与上下文机制的钥匙——掌握了它就等于掌握了整个 Preact Query 应用的“供电总线”。【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/query创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价