TanStack Lit Query 的 Accessor 类型:让查询选项同时支持静态值与响应式 Getter

发布时间:2026/10/26 12:11:17

TanStack Lit Query 的 Accessor 类型:让查询选项同时支持静态值与响应式 Getter TanStack Lit Query 的 Accessor 类型让查询选项同时支持静态值与响应式 Getter【免费下载链接】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本文围绕tanstack/lit-query的核心类型别名AccessorT展开它是 Lit Query 全部控制器 API 的响应式入口允许把查询/变更mutation选项以静态对象或零参 getter 两种形式传入。读完本文你将理解Accessor的定义与readAccessor读取机制、它在控制器生命周期中何时被求值的底层实现以及如何在 Lit 组件中正确编写静态 key 与依赖宿主状态的响应式 key。1. Accessor 的定义T | (() T)Accessor是 packages/lit-query/src/accessor.ts 中定义的类型别名type AccessorT T | () T;它的语义在源码注释中已经写得很明确accessor.ts#L1-L12A value that can be passed directly or read from a zero-argument getter. Lit Query APIs read function accessors during host updates, so the getter can depend on reactive host state.也就是说AccessorT接受两种形式静态值直接传T本身例如[todos]这样的查询 key 或完整选项对象零参 getter传一个() T函数getter 在宿主Lit 元素更新时被重新求值因此它可以闭包引用this.userId等响应式宿主状态。类型参数只有一个T表示最终被读出来的值的类型。文档给出的最小示例docs/framework/lit/reference/type-aliases/Accessor.mdconst staticKey: Accessorreadonly unknown[] [todos] const reactiveKey: Accessorreadonly unknown[] () [todos, this.userId]两者类型完全兼容——这正是该类型别名存在的全部意义让同一份 API 签名同时接纳常量配置与随宿主状态变化的配置而不需要拆成两个函数。2. 读取机制readAccessorAccessor只是类型约定真正的求值逻辑由同文件中的readAccessor函数完成accessor.ts#L15-L17export function readAccessorT(value: AccessorT): T { return typeof value function ? (value as () T)() : value }逻辑极其简洁若传入的是函数则调用它取返回值否则原样返回。整个 lit-query 包中凡是把Accessor解析为真实值的地方都走这一个函数。从源码结构看全部调用点分布在各个控制器与状态钩子中调用点解析的对象createQueryController.ts#L302readAccessor(this.options)再交给client.defaultQueryOptions(...)createMutationController.ts#L294readAccessor(this.options)再交给client.defaultMutationOptions(...)createInfiniteQueryController.ts#L342无限查询选项createQueriesController.ts#L296-L297双层解析readAccessor(optionsAccessor)后再readAccessor(resolvedOptions.queries)useIsFetching.ts#L112、useIsMutating.ts#L112过滤器条件readAccessor(this.filters)其中createQueriesController特别值得注意它把queries数组本身也定义成了Accessor因此在 types.ts#L74-L77 中QueriesControllerOptions.queries的类型是AccessorArray...——即查询列表也可以随宿主状态整体变化。3. 求值时机静态选项与函数选项的两条路径Accessor不是简单的延迟取值它在控制器内部对应两条明显不同的初始化路径。以 createQueryController.ts 为例构造函数中createQueryController.ts#L109-L133constructor(host, options, queryClient?) { const initialClient queryClient super(host, createPendingQueryResult(), queryClient) this.options options if (!initialClient) { return } if (typeof options function) { return // 函数 accessor此刻不创建 observer } const defaulted this.defaultOptions(initialClient) const observer new QueryObserver(initialClient, defaulted) ... }可以推断出两条路径的行为差异静态选项构造时立即readAccessor求值、创建QueryObserver并计算乐观结果挂载后马上订阅函数选项构造时直接返回把求值推迟到宿主更新阶段——QueryController.onHostUpdate()createQueryController.ts#L153-L159protected onHostUpdate(): void { if (typeof this.options ! function) { return // 静态选项无需在每次更新时重读 } this.refreshOptions() }refreshOptions最终通过defaultOptions里的readAccessor(this.options)createQueryController.ts#L302重新执行 getter得到与当前宿主状态一致的新选项再通过observer.setOptions(options)应用到观测器上。onHostUpdate的触发源头是 Lit 的 ReactiveController 生命周期BaseController.hostUpdate() 在每次宿主更新时回调它而结果变化后setResult→queueUpdateBaseController.ts#L159-L171会用queueMicrotask触发host.requestUpdate()从而完成getter 读宿主状态 → 选项变化 → observer 更新 → 结果变化 → 宿主重渲染的响应式闭环。createMutationController、createInfiniteQueryController等采用完全相同的模式如 createMutationController.ts#L173-L179。这正是文档中那句 Lit Query APIs read function accessors during host updates 的具体含义getter 的求值不是任意的而是绑定在 Lit 的hostUpdate回调上天然与响应式状态同步且不会在非渲染时机重复求值。4. 在控制器 API 中的实际形态Accessor是 lit-query 对外 API 签名的通用包裹。types.ts 中导出的选项类型全部是Accessor 包裹的选项// QueryControllerOptions AccessorCreateQueryOptions... export type QueryControllerOptions... Accessor CreateQueryOptionsTQueryFnData, TError, TData, TQueryData, TQueryKey // InfiniteQueryControllerOptions、MutationControllerOptions 同理 export type MutationControllerOptions... Accessor CreateMutationOptionsTData, TError, TVariables, TOnMutateResult 因此所有create*Controller工厂函数的第二个参数都是Accessor...类型。index.ts#L5 已将Accessor与ValueAccessor一起从包入口导出供组件作者自行标注 props 或内部工具类型。一个依赖宿主状态的完整用法示意userId为响应式 state 属性getter 每次宿主更新时重读import { LitElement, html } from lit import { createQueryController } from tanstack/lit-query class UserTodosView extends LitElement { private userId 1 private readonly todos createQueryController(this, () ({ queryKey: [todos, this.userId], queryFn: () fetch(/api/users/${this.userId}/todos).then((r) r.json()), })) render() { const query this.todos() if (query.isPending) return htmlLoading... if (query.isError) return htmlError return htmlul${query.data.map((t) htmlli${t.title}/li)}/ul } }注意当userId变化、宿主重新渲染时onHostUpdate会用新选项重建 observer 的 options查询随之切换。若选项与宿主状态无关直接传静态对象如仓库示例 examples/lit/basic/src/main.ts#L54-L60 中的{ queryKey: [todos], queryFn: fetchTodosFromServer }即可构造期即完成初始化省去更新期的重读开销。5. 兄弟类型ValueAccessor与createValueAccessor读Accessor时应一并了解同文件定义的另一个类型ValueAccessorTaccessor.ts#L32-L43两者方向相反、配合使用export type ValueAccessorT (() T) { readonly current: T } export function createValueAccessorT(getter: () T): ValueAccessorT { const accessor (() getter()) as ValueAccessorT Object.defineProperty(accessor, current, { get: getter, enumerable: true, }) return accessor }输入方向AccessorT——API 接受值或 getter输出方向ValueAccessorT——控制器返回可调用 带current属性的对象createValueAccessor通过Object.defineProperty让current成为一个实时 getter。createQueryController的返回值QueryResultAccessor就是ValueAccessorQueryObserverResult { refetch, suspense, destroy }createQueryController.ts#L42-L51所以渲染代码中this.todos()与this.todos.current等价。源码注释中的示例accessor.ts#L26-L30const query this.todos() const sameQuery this.todos.current这样Accessor系列类型在 lit-query 中构成了一个完整的对称设计宿主状态经Accessor流入控制器控制器结果经ValueAccessor流出到渲染代码。6. 使用建议与小结结合源码行为使用Accessor时可以遵循几条经验与宿主状态无关的选项传静态对象。静态选项在构造期即完成 observer 初始化createQueryController.ts#L128-L132且跳过每次hostUpdate中的重读分支依赖 props/state 的选项传 getter。getter 会在宿主更新时被readAccessor求值闭包捕获的this.xxx总是最新值无需手动重建控制器getter 应保持零参且轻量。它可能随宿主更新频繁执行应避免在其中发起请求或产生副作用求值结果会直接交给defaultQueryOptions/defaultMutationOptions参与 observer 合并queries列表、filters过滤器同样支持Accessor例如useIsFetching(this, () ({ queryKey: [todos, this.userId] }))。AccessorT看起来只是一行联合类型但它是 Lit Query 将 Lit 响应式生命周期与 TanStack Query 观察者模型对接的关键抽象一行T | (() T)配合readAccessor与hostUpdate钩子让声明式配置与响应式配置在同一组 API 签名下无缝共存。【免费下载链接】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),仅供参考
延伸阅读

更多相关文章

2026/10/25 16:53:48

Unity 3D扫描线动态着色实现原理与工程实践

1. 项目概述:为什么“动态着色”的3D扫描线在Unity里不是炫技,而是刚需? “动态着色”这个词在Unity社区里常被当成美术效果的修饰语,但落到“3D扫描线”这个具体任务上,它立刻从视觉糖霜变成工程硬需求。我第一次接到…

2026/10/25 23:31:23

transformers.js 源码解析:前端 Transformer 推理与 ONNX Runtime 实践

先说一下我为什么会对这个项目起劲。以前要在浏览器里跑一个 BERT,大家第一反应都是 TensorFlow.js,但真到用的时候就发现坑很多:模型转换要自己处理、tokenizer 的对齐方式经常对不上、动态 shape 一调就是半天。后来 Hugging Face 做了 tra…

2026/10/26 12:08:15

科研AI新范式:用思想拓扑图破解文献阅读到创新跃迁的断点

1. 这不是又一个“AI写论文”工具——它在解决科研者最隐秘的卡点你有没有过这样的时刻:读完一篇顶会论文,合上PDF,心里清楚“这工作很扎实”,但脑子里却像蒙着一层雾——它到底打开了哪扇门?如果我来跟进,…

2026/10/26 12:08:15

Linux服务器性能调优实战指南

1. Linux服务器运维调优的核心价值与场景定位 在当今企业级IT基础设施中,Linux服务器作为承载关键业务的主力平台,其性能表现直接影响着用户体验和运营成本。我曾亲历过一个电商大促场景:当并发请求量突破5万QPS时,未经调优的Ngin…

2026/10/26 12:08:15

Hadoop大数据处理入门与实战指南

1. Hadoop入门:为什么每个大数据工程师都要从这里开始 第一次接触Hadoop的场景至今记忆犹新——那是在处理一个包含3000万条用户行为记录的数据集时,我的Excel和Access已经卡得完全无法响应。当时团队里的资深工程师只说了一句:"该上Had…

2026/10/26 12:08:15

全景拼接工程化重写:从能拼到准稳省的三阶跃迁

1. 为什么“再写-全景拼接”不是重复劳动,而是技术迭代的必然动作“再写-全景拼接”这个标题乍看像一句自嘲——拼接算法早不是新鲜事,OpenCV里Stitcher类几行代码就能跑通Demo,网上教程铺天盖地,连本科生课程设计都在做。但过去三…

2026/10/26 12:08:15

open62541 V1.4 开发包实战:从编译到OPC UA服务端与客户端开发

简介:面向工业自动化与物联网方向的C开发者,这份资源提供OPC UA开源实现open62541的V1.4版SDK,用于快速搭建符合OPC统一架构规范的服务器与客户端程序,适合具备一定C基础、希望切入工业数据交换领域的中级开发者。压缩包共4个文件…

2026/10/26 12:03:14

2026年数据驱动型寒假集训技术方案解析

1. 项目背景与核心价值 寒假集训作为教育领域的经典学习模式,在2026年这个时间节点呈现出新的技术特征。这次为期25天的集中训练,不同于传统补习班单向灌输的模式,而是融合了智能分组、自适应学习、实时反馈等数字化教学手段。我参与过七届不…

2026/10/26 0:20:20

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/26 1:53:47

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/26 0:20:17

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/26 0:00:48

Nested Learning:解决AI灾难性遗忘的分层记忆架构

1. 为什么AI需要"记忆"能力?在传统深度学习模型中,我们常遇到一个根本性问题:模型在处理新任务时,往往会完全遗忘之前学到的知识。这种现象被业界称为"灾难性遗忘"(Catastrophic Forgetting)。想象一下&#…

2026/10/26 0:00:48

企业级大模型应用:OCR预处理、Dify编排与DeepSeek落地实战

1. 这不是“用大模型”,而是重构工作流的起点“大模型的应用和工具”——这八个字现在被贴在无数技术分享、招聘JD、内部立项书的标题栏里,但绝大多数人点进去后看到的,是零散的API调用示例、几个开源UI截图、或者一句“接入LLM就能降本增效”…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑