AdminJS useResource Hook 完全指南:从 Redux 资源状态中按 ID 获取 ResourceJSON
后端低代码【免费下载链接】adminjsAdminJS is an admin panel for apps written in node.js项目地址https://gitcode.com/gh_mirrors/ad/adminjs点击查看免费下载useResource是 AdminJS 前端内置的一个 React Hook用于从 Redux Store 中按资源 ID 获取对应的ResourceJSON对象。本指南将围绕该 Hook 的用法、返回数据结构、底层实现原理以及在自定义组件中的实战场景展开帮助你快速上手 AdminJS 前端定制。导读useResource是 AdminJS 前端组件体系中一个轻量但高频使用的 Hook。当你在自定义 Record Action 组件、路由页面或任何需要感知资源元数据属性、动作、导航信息的组件中工作时useResource都能帮你从全局 Redux Store 中按 ID 快速取出对应资源的完整 JSON 描述。读完本文你将掌握useResource的调用方式与返回类型、ResourceJSON的完整字段结构以及该 Hook 在 src/frontend/hooks/use-resource/use-resource.ts 中的实现原理并能在自己的自定义组件中实际运用。官方文档原文useResource的官方文档位于 src/frontend/hooks/use-resource/use-resource.doc.md原文如下The hook which allows you to get {link ResourceJSON} object for a particular resource ID from the store.Usageimport { useResource } from adminjs const MyRecordActionComponent (props) { const UsersResource useResource(Users) const { properties } UsersResource // .... } export default MyRecordActionComponent该文档定义了一个核心功能通过资源 ID 从 Store 中获取对应的ResourceJSON对象。下面我们将基于该文档展开深入讲解。一、基础用法按资源 ID 获取 ResourceJSONuseResource的签名非常简单只接受一个参数const useResource (resourceId: string): ResourceJSON | undefined参数resourceId你希望获取的资源的唯一标识符字符串。返回值ResourceJSON对象若未找到匹配的资源则返回undefined。基本示例import { useResource } from adminjs const MyRecordActionComponent (props) { const UsersResource useResource(Users) // 获取该资源的所有属性含嵌套属性映射 const { properties } UsersResource // 获取列表视图展示的属性数组 const { listProperties } UsersResource // 获取资源级动作如 new、list、search const { resourceActions } UsersResource // ... 你的自定义逻辑 } export default MyRecordActionComponent注意resourceId必须与后端注册资源时使用的 ID 完全一致例如Users、Article、OrderItem等。若传入不存在的 IDHook 会返回undefined因此在解构字段前建议先做空值保护例如if (resource) { ... }。二、返回对象ResourceJSON 结构详解useResource返回的ResourceJSON是前端对后端资源的 JSON 化描述定义于 src/frontend/interfaces/resource-json.interface.ts。其完整字段如下字段类型说明idstring资源的唯一标识符namestring资源名称hrefstring \| null资源列表动作的 URL若为null资源不应出现在侧边栏中navigation{ name, icon, show } \| null资源的父级导航信息侧边栏可见含父级名称、图标与可见性titlePropertyBasePropertyJSON应被视为“主属性”的属性通常用于展示记录标题resourceActionsArrayActionJSON该资源可用的资源级动作如 new、list、searchactionsArrayActionJSON所有动作无论当前是否可用listPropertiesArrayBasePropertyJSON列表视图中可见的属性editPropertiesArrayBasePropertyJSON编辑视图中可见的属性showPropertiesArrayBasePropertyJSON详情show视图中可见的属性filterPropertiesArrayBasePropertyJSON筛选器中可见的属性propertiesRecordstring, BasePropertyJSON资源内所有属性的映射包含嵌套属性这是获取任意属性的最便捷方式2.1 属性描述BasePropertyJSONBasePropertyJSON定义于 src/frontend/interfaces/property-json/property-json.interface.ts它是PropertyJSON去掉path字段后的类型OmitPropertyJSON, path。PropertyJSON包含的关键字段有name/propertyPath属性名称与唯一路径嵌套属性使用点号记法如nested.propertylabel属性在界面上的显示标签type属性类型来自PropertyType如 string、number、datetime、boolean、reference 等isTitle/isId是否为标题属性或主键属性isSortable/isRequired/isDisabled/hideLabel排序、必填、禁用、隐藏标签等标志reference若属性是对其他资源的引用这里保存被引用资源的名称如属性userId会得到UsersisArray/isDraggable是否为数组属性、数组项是否可拖拽subProperties子属性列表适用于 MongoDB 等嵌套 schemacomponents用户在PropertyOptions中覆盖的组件名custom/props自定义参数与传给 React 组件的附加 propsresourceId属性所属资源的 IDisVirtual是否由 AdminJSPropertyOptions虚拟创建数据库适配器未返回的属性。2.2 动作描述ActionJSONActionJSON定义于 src/frontend/interfaces/action/action-json.interface.ts它描述了一个动作的 JSON 形态关键字段包括name动作唯一名称actionType动作类型取值为record、resource或bulklabel前端可见的动作标签icon/variant/color动作图标、样式变体与颜色guard点击动作按钮后alert()展示的确认信息showFilter/showResourceActions是否显示筛选器、是否在动作标题上方显示资源动作按钮component动作组件设为false时点击动作将直接执行无动作视图showInDrawer/hideActionHeader/containerWidth抽屉展示、隐藏动作标题、容器宽度等界面行为resourceId动作所属资源 IDlayoutAction#layout解析后的布局元素数组hasHandler是否定义了动作处理器custom从动作配置传入的自定义选项。三、底层实现原理useResource的实现非常精简位于 src/frontend/hooks/use-resource/use-resource.tsimport { useSelector } from react-redux import { ResourceJSON } from ../../interfaces/resource-json.interface.js import { ReduxState } from ../../store/store.js const useResource (resourceId: string): ResourceJSON | undefined { const resources useSelector((state: ReduxState) state.resources) const foundResource resources.find((resource) resource.id resourceId) return foundResource }从源码结构可以看出其核心机制使用useSelector订阅 Redux StoreHook 通过useSelector从ReduxState中取出state.resources一个ArrayResourceJSON。线性查找通过Array.prototype.find在资源数组中查找id resourceId的资源找到则返回该资源对象否则返回undefined。响应式更新得益于 React-Redux 的订阅机制当state.resources变化时使用该 Hook 的组件会自动重新渲染。3.1 数据从哪来resources Reducer 与初始化 Actionstate.resources由resourcesReducer管理定义于 src/frontend/store/reducers/resourcesReducer.tsexport const resourcesReducer ( state: ResourcesInState [], action: { type: string; data: ResourcesInState }, ) { switch (action.type) { case RESOURCES_INITIALIZE: return action.data default: return state } }该 Reducer 的初始状态为空数组[]仅在收到RESOURCES_INITIALIZE动作时用动作携带的data整体替换state。RESOURCES_INITIALIZE动作由initializeResources工厂函数创建定义于 src/frontend/store/actions/initialize-resources.tsexport const RESOURCES_INITIALIZE RESOURCES_INITIALIZE export const initializeResources (data: ArrayResourceJSON): InitializeResourcesResponse ({ type: RESOURCES_INITIALIZE, data, })也就是说AdminJS 在应用初始化时会一次性将后端序列化好的全部资源 JSON 写入 Store此后useResource只是对这个全局资源表做按 ID 的查询。3.2 Store 结构定位ReduxState定义于 src/frontend/store/store.ts其中resources: ResourcesInState即ArrayResourceJSON是全局 Store 的一个顶层切片。此外 Store 还包含assets、branding、dashboard、drawer、filterDrawer、locale、modal、notices、pages、paths、router、session、theme、versions等切片useResource仅关心resources这一项。四、与其他 Hook 的关联useResource属于 AdminJS 前端 Hooks 体系的一员在 src/frontend/hooks/index.ts 中与其他 Hook 一并对外导出export * from ./use-action/index.js export * from ./use-current-admin.js export * from ./use-filter-drawer.js export * from ./use-history-listen.js export * from ./use-local-storage/index.js export * from ./use-modal.js export * from ./use-navigation-resources.js export * from ./use-notice.js export * from ./use-query-params.js export * from ./use-record/index.js export * from ./use-records/index.js export * from ./use-resource/index.js export * from ./use-selected-records/index.js export * from ./use-translation.js与之互补的 Hook 包括useRecord/useRecords分别管理单条记录与记录列表的状态useAction触发动作并处理响应useSelectedRecords管理批量选中记录useNavigationResources基于ResourceJSON.navigation构建侧边栏导航分组。实际使用中useResource常常与useAction、useRecord组合先用useResource拿到资源的动作与属性元数据再用useAction构建并触发动作或用useRecord维护记录表单状态。五、在自定义组件中的实战示例官方文档给出的场景是自定义 Record Action 组件。以下扩展为更完整的实战示例import { useResource, useRecord } from adminjs const MyRecordActionComponent (props) { const { record, resource: resourceFromProps } props // 方式一通过 Hook 按 ID 获取资源元数据 const resourceFromStore useResource(record.resourceId) // 方式二使用 props 中注入的 resource const resource resourceFromStore || resourceFromProps // 获取资源所有属性含嵌套属性例如按名称取单个属性 const emailProperty resource.properties[email] const { label, type, isRequired } emailProperty // 判断资源是否有某个资源级动作 const hasNewAction resource.resourceActions.some((a) a.name new) return ( div h3资源{resource.name}/h3 p属性 email 的类型{type}必填{isRequired}/p p是否有 new 动作{hasNewAction ? 是 : 否}/p /div ) } export default MyRecordActionComponent5.1 空值保护与容错由于useResource在找不到资源时返回undefined建议在解构前做空值检查const resource useResource(NonExistentResource) if (!resource) { return div资源不存在/div }5.2 获取嵌套属性ResourceJSON.properties是一个Recordstring, BasePropertyJSON映射包含嵌套属性因此即使属性位于深层嵌套结构如 MongoDB 的嵌套 schema也能通过完整路径直接获取const resource useResource(Orders) const addressCityProperty resource.properties[address.city] // 嵌套属性路径六、AdminJS 内置使用场景useResource并非只能用于自定义组件AdminJS 自身也大量使用该 Hook 完成路由页面的资源元数据获取。从源码搜索结果看以下内置路由均依赖它src/frontend/components/routes/bulk-action.tsx批量动作路由通过useResource(resourceId!)获取资源再据此渲染批量动作界面src/frontend/components/routes/record-action.tsx记录动作路由通过useResource(resourceId!)获取资源后渲染动作视图。这些内置使用可以看作useResource的官方参考实现先取资源再从resourceActions中按动作名查找目标动作、读取containerWidth、showInDrawer等界面配置最后将action与resource一并传给BaseActionComponent渲染。七、常见问题与注意事项资源 ID 大小写敏感useResource使用严格相等比较resource.id与传入的resourceId因此传入的 ID 必须与后端注册资源时的 ID 完全一致如Users不能写成users。返回值可能为undefined当资源尚未初始化或 ID 不存在时返回undefined务必做空值保护。与 props 注入的资源区别AdminJS 内置组件通常通过 props 传入resource而useResource是从全局 Store 中主动查询。在自定义组件中两者等价可用但 props 注入的资源在组件被复用时可能更贴近调用方上下文。性能考量由于实现为Array.prototype.find线性查找在资源数量极多的大型应用中若在大量列表项组件内频繁调用可考虑在父组件中只调用一次useResource并通过 props 向下传递避免重复查找。八、总结useResource(resourceId)是一个聚焦单一职责的 Hook从 AdminJS 全局 Redux Store 的资源表中按资源 ID 返回对应的ResourceJSON。它的数据由initializeResources动作在应用启动时注入由resourcesReducer维护最终通过useSelectorfind提供给组件。掌握了ResourceJSON的字段结构属性分组、动作列表、导航信息、嵌套属性映射你就能在自定义动作组件、页面组件中自由读取资源元数据构建属于自己的 AdminJS 前端定制逻辑。相关资源仓库内路径Hook 实现src/frontend/hooks/use-resource/use-resource.ts官方文档src/frontend/hooks/use-resource/use-resource.doc.md返回类型定义src/frontend/interfaces/resource-json.interface.ts属性类型定义src/frontend/interfaces/property-json/property-json.interface.ts动作类型定义src/frontend/interfaces/action/action-json.interface.tsStore 结构src/frontend/store/store.tsReducersrc/frontend/store/reducers/resourcesReducer.ts初始化 Actionsrc/frontend/store/actions/initialize-resources.tsHooks 统一出口src/frontend/hooks/index.ts赞分享后端低代码【免费下载链接】adminjsAdminJS is an admin panel for apps written in node.js项目地址https://gitcode.com/gh_mirrors/ad/adminjs点击查看免费下载相关推荐LX Music 桌面版快速指南免费多源音乐搜索、批量下载与播放LX Music 桌面版快速指南免费多源音乐搜索、批量下载与播放 想听的歌散在三四个不同的音乐 App 里LX Music 桌面版Apache 2.0E桌面应用音视频前端Relay 中 useRelayEnvironment Hook 完全指南从 Context 中安全获取 EnvironmentRelay 中 useRelayEnvironment Hook 完全指南从 Context 中安全获取 Environment useRelayEnviro前端开发工具Cytoscape.js 按 ID 高效获取元素cy.getElementById() 与 cy.$id() 完整指南Cytoscape.js 按 ID 高效获取元素cy.getElementById 与 cy.$id 完整指南 cy.getElementById id 是数据可视化上一篇WavTap vs 其他音频录制工具为什么这款Mac音频捕获神器能脱颖而出下一篇CubeSandbox O(1)快照克隆原理FICLONE reflink零拷贝深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Buildah ONBUILD 实战指南:让基础镜像的触发指令自动注入派生镜像

Buildah ONBUILD 实战指南:让基础镜像的触发指令自动注入派生镜像

云原生 【免费下载链接】buildah A tool that facilitates building OCI images. 项目地址: https://gitcode.com/gh_mirrors/bu/buildah 点击查看 免费下载 本文以 Buildah 官方教程 docs/tutorials/03-on-build.md 为主体,系统讲解 ONBUILD 指令在 Bu…

2026/9/25 3:28:49 阅读更多 →
MCP Streamable HTTP 传输的 SSE 轮询机制:SEP-1699 服务端主动断开(Server-Side Disconnect)规范解读

MCP Streamable HTTP 传输的 SSE 轮询机制:SEP-1699 服务端主动断开(Server-Side Disconnect)规范解读

人工智能AI Agent工具调用 【免费下载链接】specification Specification and documentation for the Model Context Protocol 项目地址: https://gitcode.com/gh_mirrors/specification2/specification 点击查看 免费下载 导读:SEP-1699(St…

2026/9/25 3:27:48 阅读更多 →
Loop Engineering 研究与实践:oh-my-opencode-slim 的五块积木、Ralph 循环与最小闭环

Loop Engineering 研究与实践:oh-my-opencode-slim 的五块积木、Ralph 循环与最小闭环

人工智能AI AgentAgent 编排AI 技能 【免费下载链接】oh-my-opencode-slim Lean, fine tuned Opencode multi agent suite Mix any models Auto delegate tasks 项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-opencode-slim 点击查看 免费下载 本文以仓库内…

2026/9/25 3:27:48 阅读更多 →

最新新闻

OpenClaw 部署安全指南:从会话锁到提示注入的完整防护

OpenClaw 部署安全指南:从会话锁到提示注入的完整防护

本来我想先夸一夸 OpenClaw 这玩意儿本地跑起来有多爽,但这篇文章还是直接从风险讲起吧。你把它部署好、接到 Teams 或飞书上、再配上千问之类的模型,它就从一个普通程序变成了一个常驻代理:能读文件、能发消息、能调 API、还能替你执行命令。…

2026/9/25 4:49:42 阅读更多 →
宏集DC-Pi工业控制器:融合PLC、HMI与边缘AI的工程实践

宏集DC-Pi工业控制器:融合PLC、HMI与边缘AI的工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:49:42 阅读更多 →
Windows 10强制关机脚本:原理、权限与企业级落地

Windows 10强制关机脚本:原理、权限与企业级落地

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:49:42 阅读更多 →
油猴脚本防暂停原理与实战:浏览器自动化技术解析

油猴脚本防暂停原理与实战:浏览器自动化技术解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:49:42 阅读更多 →
微信公众号历史文章列表页获取实战指南

微信公众号历史文章列表页获取实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:49:41 阅读更多 →
Ubuntu 22.04 Server 安装与初始化配置全攻略

Ubuntu 22.04 Server 安装与初始化配置全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:48:41 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →