多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Refine v5 Chakra UI Inferencer 完整指南:用 `@refinedev/inferencer/chakra-ui` 自动生成 CRUD 页面

Refine v5 Chakra UI Inferencer 完整指南:用 `@refinedev/inferencer/chakra-ui` 自动生成 CRUD 页面 Refine v5 Chakra UI Inferencer 完整指南用refinedev/inferencer/chakra-ui自动生成 CRUD 页面【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine导读在 Refine v5 项目中为每个 resource 手写 List / Show / Create / Edit 四类页面既重复又耗时。refinedev/inferencer是 Refine 官方提供的页面推断器它先向 dataProvider 请求真实数据再根据 API 返回的记录结构自动推断字段类型最后生成可直接运行的 Chakra UI 页面代码。本文以仓库中的 Chakra UI Inferencer 文档 为核心讲解ChakraUIInferencer及其四个子组件的两种接入方式、四种视图的生成逻辑并结合 inferencer 包源码 剖析字段推断 → 代码生成 → 实时渲染的完整链路。读完本文你将掌握用一行组件为任意 resource 搭建整套 CRUD 界面并能按需定制、提取生成的代码用于生产。什么是 Inferencerrefinedev/inferencer是一个通用推断引擎Chakra UI 只是它支持的 UI 适配层之一仓库中还包含 antd、MUI、Mantine、headless 等适配见 inferencers 目录。针对 Chakra UI它导出以下组件组件对应页面ChakraUIListInferencer列表页ListChakraUIShowInferencer详情页ShowChakraUICreateInferencer新建页CreateChakraUIEditInferencer编辑页EditChakraUIInferencer以上四者的组合根据当前路由自动分发所有组件统一从refinedev/inferencer/chakra-ui子路径导入。组合组件ChakraUIInferencer的源码位于 packages/inferencer/src/inferencers/chakra-ui/index.tsx其分发逻辑如下优先使用传入的actionprop否则调用useParsed()从当前 URL 解析出action与id再分别渲染对应页面——默认无法匹配时回退到 List 页面。安装与导入Inferencer 独立于核心包分发需要额外安装npm install refinedev/inferencer使用 Chakra UI 适配时项目还需同时具备refinedev/chakra-ui、refinedev/react-table、refinedev/react-hook-form与chakra-ui/react依赖原因见下文四种视图的生成逻辑。导入方式import { ChakraUIInferencer } from refinedev/inferencer/chakra-ui;也可以按页面单独导入import { ChakraUIListInferencer, ChakraUIShowInferencer, ChakraUICreateInferencer, ChakraUIEditInferencer, } from refinedev/inferencer/chakra-ui;用法一注册到 resources 的路由中零 props 接入这是最省事的接入方式。由于组件挂载在resources声明的路由之下配合routerProviderInferencer 会自动从当前路由推断出resource、action和id因此无需传入任何 propsimport { Layout, refineTheme } from refinedev/chakra-ui; import { ChakraProvider } from chakra-ui/react; import { BrowserRouter, Routes, Route, Outlet } from react-router; import { ChakraUIInferencer } from refinedev/inferencer/chakra-ui; const App () { return ( ChakraProvider theme{refineTheme} BrowserRouter Refine routerProvider{routerProvider} resources{[ { name: samples, list: /samples, }, ]} Routes Route path/samples element{ChakraUIInferencer /} / /Routes /Refine /BrowserRouter /ChakraProvider ); };只要在resources中为 resource 声明了list/show/create/edit对应的路由路径并把该路径的element设为ChakraUIInferencer /访问/samples、/samples/show/123、/samples/create、/samples/edit/123就能分别得到列表、详情、新建、编辑四种页面无需为每个 action 单独注册组件。用法二在自定义组件中使用显式传 props当你不想依赖路由推断或想把推断结果嵌入某个自定义页面的局部区域时可以显式传入resource、action、idimport { ChakraUIInferencer } from refinedev/inferencer/chakra-ui; const SampleList () { return ChakraUIInferencer resourcesamples actionlist /; }; const SampleShow () { return ChakraUIInferencer resourcesamples actionshow id1 /; }; const SampleCreate () { return ChakraUIInferencer resourcesamples actioncreate /; }; const SampleEdit () { return ChakraUIInferencer resourcesamples actionedit id1 /; };注意id只在show和edit场景有意义list与create不需要id。这两种用法可混合组合组件会优先采用 props 中的值缺省项再回退到路由解析结果见 index.tsx。四种视图的生成逻辑Inferencer 的四种页面分别对应不同的底层 hook 与 UI 组合原文档给出了四组基于https://api.fake-rest.refine.dev的完整可运行示例。为便于阅读这里去除文档中仅用于在线 Playground 的setInitialRoutes/render包装代码保留核心应用结构。List数据表 分页列表页根据 API 响应生成示例列表视图。它使用refinedev/chakra-ui的List组件、refinedev/react-table的useTablehook底层由 TanStack Table 驱动并附带usePagination分页条import { Refine } from refinedev/core; import { ThemedLayout, RefineThemes } from refinedev/chakra-ui; import { ChakraProvider } from chakra-ui/react; import routerProvider from refinedev/react-router; import dataProvider from refinedev/simple-rest; import { BrowserRouter, Routes, Route, Outlet } from react-router; import { ChakraUIInferencer } from refinedev/inferencer/chakra-ui; const API_URL https://api.fake-rest.refine.dev; const App: React.FC () { return ( ChakraProvider theme{RefineThemes.Blue} BrowserRouter Refine routerProvider{routerProvider} dataProvider{dataProvider(API_URL)} resources{[ { name: samples, list: /samples, }, ]} Routes Route element{ ThemedLayout Outlet / /ThemedLayout } Route path/samples element{ChakraUIInferencer /} / /Route /Routes /Refine /BrowserRouter /ChakraProvider ); };Show字段描述 关联数据详情页根据 API 响应生成记录展示视图使用refinedev/chakra-ui的Show与各*Field组件数据获取由refinedev/core的useShow完成import { Refine } from refinedev/core; import { ThemedLayout, RefineThemes } from refinedev/chakra-ui; import { ChakraProvider } from chakra-ui/react; import routerProvider from refinedev/react-router; import dataProvider from refinedev/simple-rest; import { BrowserRouter, Routes, Route, Outlet } from react-router; import { ChakraUIInferencer } from refinedev/inferencer/chakra-ui; const API_URL https://api.fake-rest.refine.dev; const App: React.FC () { return ( ChakraProvider theme{RefineThemes.Blue} BrowserRouter Refine routerProvider{routerProvider} dataProvider{dataProvider(API_URL)} resources{[ { name: samples, show: /samples/show/:id, }, ]} Routes Route element{ ThemedLayout Outlet / /ThemedLayout } Route path/samples/show/:id element{ChakraUIInferencer /} / /Route /Routes /Refine /BrowserRouter /ChakraProvider ); };Create表单 字段控件新建页根据列表接口返回的第一条记录推断出表单字段并生成示例创建视图使用refinedev/chakra-ui的Create组件与refinedev/react-hook-form的useFormimport { Refine } from refinedev/core; import { ThemedLayout, RefineThemes } from refinedev/chakra-ui; import { ChakraProvider } from chakra-ui/react; import routerProvider from refinedev/react-router; import dataProvider from refinedev/simple-rest; import { BrowserRouter, Routes, Route, Outlet } from react-router; import { ChakraUIInferencer } from refinedev/inferencer/chakra-ui; const API_URL https://api.fake-rest.refine.dev; const App: React.FC () { return ( ChakraProvider theme{RefineThemes.Blue} BrowserRouter Refine routerProvider{routerProvider} dataProvider{dataProvider(API_URL)} resources{[ { name: samples, create: /samples/create, }, ]} Routes Route element{ ThemedLayout Outlet / /ThemedLayout } Route path/samples/create element{ChakraUIInferencer /} / /Route /Routes /Refine /BrowserRouter /ChakraProvider ); };Edit回填表单 关联选择编辑页根据 API 响应生成示例编辑视图同样基于refinedev/chakra-ui的Edit组件与refinedev/react-hook-form的useForm并通过useSelect将关联字段渲染为下拉选择框import { Refine } from refinedev/core; import { ThemedLayout, RefineThemes } from refinedev/chakra-ui; import { ChakraProvider } from chakra-ui/react; import routerProvider from refinedev/react-router; import dataProvider from refinedev/simple-rest; import { BrowserRouter, Routes, Route, Outlet } from react-router; import { ChakraUIInferencer } from refinedev/inferencer/chakra-ui; const API_URL https://api.fake-rest.refine.dev; const App: React.FC () { return ( ChakraProvider theme{RefineThemes.Blue} BrowserRouter Refine routerProvider{routerProvider} dataProvider{dataProvider(API_URL)} resources{[ { name: samples, edit: /samples/edit/:id, }, ]} Routes Route element{ ThemedLayout Outlet / /ThemedLayout } Route path/samples/edit/:id element{ChakraUIInferencer /} / /Route /Routes /Refine /BrowserRouter /ChakraProvider ); };各视图的依赖 hook 一览视图UI 组件refinedev/chakra-ui数据/表单 hook数据源ListList、TagField、EmailField、UrlField、BooleanField、DateField、MarkdownField、EditButton、ShowButton、DeleteButtonuseTablerefinedev/react-table、usePagination、useMany列表接口ShowShow、各*FielduseShowrefinedev/core、useOne/useMany详情接口CreateCreate、FormControl、Input、Select、Checkbox等useFormrefinedev/react-hook-form、useSelect列表接口第一条记录EditEdit、同 Create 的表单控件useFormrefinedev/react-hook-form、useSelect详情接口深入源码Inferencer 是如何推断出来的ChakraUIInferencer之所以能自动生成代码是因为所有 UI 适配都复用了同一个核心工厂 create-inferencer/index.tsx完整链路为取数useInferFetch根据typelist/show/create/edit向当前 resource 发起对应的 dataProvider 请求拿到一条或多条真实记录useResourceParams负责从 props 或路由解析 resource。字段推断对记录逐字段执行infer(key, value, record, infer, type)得到带类型的InferField[]。默认推断器注册于 field-inferencers/index.ts共 12 类array、boolean、date、email、image、nullish、number、object、relation、richtext、text、url。字段变换composeTransformers组合默认变换器如basic-to-relation、image-by-key、relation-by-resource对推断结果做二次加工把基本字段升级为关联字段并绑定目标 resource。关系数据补取useRelationFetch为关联字段补齐useMany/useOne/useSelect所需的数据。生成代码调用各 UI 的renderer函数把推断出的字段映射为字符串代码再由react-live实时渲染并在代码查看器中展示可复制的源码。字段类型推断的判定规则推断器按值类型 字段名双重信号工作。以最基础的文本为例text.ts 只判断typeof value string而关系字段则更讲究——relation.ts 使用正则export const relationRegexp /(-id|-ids|_id|_ids|Id|Ids|ID|IDs)(\[\])?$/;凡是字段名以-id、_id、Id、IDs等结尾且值为基本类型string/number或其数组就会被判定为关系字段type: relation并在后续变换中尝试映射到同名 resource。date、email、image、url、richtext、boolean等类型同样由独立的推断器判定最终映射到 Chakra UI 的DateField、EmailField、Image、UrlField、MarkdownField、BooleanField等组件。List 渲染器中的关系字段处理以列表页渲染器 chakra-ui/list.tsx 为例对每个relation字段渲染器会生成一个useMany调用收集所有关联 id再通过setOptions把结果注入 TanStack Table 的meta在cell渲染函数里按id查找关联记录并显示其可读字段若关联字段是数组multiple则渲染为一组TagField。图片字段会生成Image富文本字段会用MarkdownField截断为前 80 个字符加省略号。动作按钮的智能生成List 渲染器还会根据 resource 的能力自动决定是否生成操作列见 list.tsxresource 声明了show或meta.canShow→ 生成ShowButtonresource 声明了edit或meta.canEdit→ 生成EditButtonresource 声明了meta.canDelete→ 生成DeleteButton对应地示例应用 中的blog_posts与categories两个 resource 都在meta中声明了canDelete: true因此生成的列表页会自带删除按钮。组件 Props 详解组合与子组件的完整 Props 定义见 packages/inferencer/src/types/index.tsProp类型说明name/resourcestring要推断的 resource 名称二者任选其一actionlist \| show \| edit \| create要生成的页面类型默认listidstring \| number记录 idshow/edit场景必填或由路由提供fieldTransformer(field: InferField) InferField \| undefined \| null \| false字段变换函数返回undefined/null/false可隐藏某字段返回新字段可改写其accessor等属性以修正渲染meta见类型定义按 resource 传递给 dataProvider 方法的额外参数如 GraphQL 的gqlQuery/gqlMutationhideCodeViewerInProductionboolean生产环境下隐藏代码查看器与信息提示块完整示例应用仓库中的 examples/inferencer-chakra-ui 是一个配置完整的可运行示例对应原文档末尾的 CodeSandbox。它演示了 Inferencer 生成代码后落地为真实页面的形态数据源https://api.fake-rest.refine.devrefinedev/simple-rest认证内置authProvider未登录跳转/login国际化i18nProvider对接react-i18next资源blog_posts与categories各含 list/create/edit/show 四条路由布局ThemedLayout包裹使用RefineThemes.Blue主题并集成RefineKbar命令面板与UnsavedChangesNotifier生成后的页面文件保存在 src/pages/blog-posts 与 src/pages/categories 下每个 resource 包含list.tsx、create.tsx、edit.tsx、show.tsx四个页面可直接对照学习 Inferencer 的产出代码风格。测试保障refinedev/inferencer为每种 UI 适配都编写了快照测试Chakra UI 的测试位于 packages/inferencer/src/inferencers/chakra-ui/tests包含create/edit/index/list/show五组用例及对应快照。这些测试锁定给定 mock 数据 → 生成稳定代码的行为确保字段推断与代码生成在迭代中不产生意外变化需要定制生成逻辑时也可以以此为参考基准。最佳实践与注意事项Inferencer 是开发脚手架不是生产组件。类型定义中明确标注hideCodeViewerInProduction的注释Inferencer 组件本身不应用于生产环境。推荐的工作流是开发期用 Inferencer 快速生成页面 → 从代码查看器复制生成的代码 → 粘贴为正式的pages文件 → 从路由中移除 Inferencer。需要完整路由配置。零 props 用法要求resources中声明对应的list/show/create/edit路径否则无法正确推断action与id。关联字段依赖 resource 命名。关系字段能否正确渲染为下拉/标签取决于字段名是否命中关系正则以及同名 resource 是否已注册。无法推断时List 单元格会渲染为Cannot Render占位并输出refinedev/inferencer: Inferencer failed to render this field日志。用fieldTransformer微调字段。隐藏敏感字段、修正嵌套访问路径等需求优先通过fieldTransformer解决而不是直接改生成代码这样在数据模型变化后可重新生成。GraphQL 项目传入meta。渲染器会检测meta中是否存在gqlQuery/gqlMutation并自动引入graphql-tag的gql为 GraphQL dataProvider 生成对应查询/变更代码。延伸阅读原文档documentation/docs/ui-integrations/chakra-ui/components/inferencer/index.md组合组件分发源码packages/inferencer/src/inferencers/chakra-ui/index.tsx推断工厂实现packages/inferencer/src/create-inferencer/index.tsx字段推断器集合packages/inferencer/src/field-inferencers/index.ts类型与 Props 定义packages/inferencer/src/types/index.ts完整示例examples/inferencer-chakra-ui【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表