ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

AdminJS useResource Hook 完全指南:从 Redux 资源状态中按 ID 获取 ResourceJSON

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),仅供参考
返回列表