ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Formily React 中 useFieldSchema Hook 完全指南:在自定义组件中读取当前字段 Schema

Formily React 中 useFieldSchema Hook 完全指南:在自定义组件中读取当前字段 Schema 前端UI组件【免费下载链接】formily Cross Device High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/React Native/Vue 2/Vue 3项目地址https://gitcode.com/gh_mirrors/fo/formily点击查看免费下载导读useFieldSchema是 Formily React 体系中专用于自定义组件开发的 Hook它的核心职责是在自定义组件内部读取当前字段的 JSON Schema 信息。本文围绕 useFieldSchema.zh-CN.md 展开详细讲解它的适用场景、使用边界、底层实现原理React Context 注入机制、完整用例并结合 schema.markup.spec.tsx 中的真实测试演示如何借助它驱动RecursionField递归渲染子 Schema。读完本文你将掌握在自定义组件中安全读取 Schema、并按需递归渲染子节点的完整实战方案。一、useFieldSchema 是什么useFieldSchema是formily/react提供的一个 React Hook主要用途是在自定义组件中读取当前字段的 Schema 信息。它返回的是一个 Schema 实例即formily/json-schema包中的Schema类通过该实例可以访问properties子属性、x-component组件名、x-component-props组件参数、x-decorator、title、default等全部 Schema 描述信息。它在 Formily 自定义组件开发中承担着元数据读取的角色当你想基于 Schema 中的声明如x-component-props、x-decorator动态渲染组件时用useFieldSchema拿到声明数据当你想在自定义组件内部继续递归渲染子 Schema对象/数组类型的子字段时通常需要把useFieldSchema()的结果传给RecursionField当你需要把 Schema 序列化为可展示的 JSON 结构调试、文档化、可视化编辑时直接调用schema.toJSON()。二、使用边界只能在 SchemaField / RecursionField 子树内使用文档明确强调了一个重要约束该 hook 只能用在 SchemaField 或者 RecursionField 的子树中使用这一点可以从源码实现得到印证。useFieldSchema的实现非常简洁本质上就是读取一个 React Context// packages/react/src/hooks/useFieldSchema.ts import { useContext } from react import { SchemaContext } from ../shared import { Schema } from formily/json-schema export const useFieldSchema (): Schema { return useContext(SchemaContext) }而SchemaContext是在 packages/react/src/shared/context.ts 中创建的export const SchemaContext createContextSchema(null)它的默认值是null因此如果在一个既不是SchemaField也不是RecursionField子树的组件里调用useFieldSchema()拿到的将是null随后访问schema.toJSON()等成员时会报错。务必保证自定义组件一定挂在 Schema 渲染树之下。三、底层原理SchemaContext 的注入机制SchemaContext的 value 是由RecursionField组件注入的。在 packages/react/src/components/RecursionField.tsx 中RecursionField在渲染子组件之前先把当前字段的fieldSchema写入 Context// packages/react/src/components/RecursionField.tsx if (!fieldSchema) return Fragment / return ( SchemaContext.Provider value{fieldSchema} {render()} /SchemaContext.Provider )也就是说每当RecursionField根据某个 Schema 节点渲染其对应组件时该组件及其所有后代都能通过useFieldSchema()拿到当前正在渲染的这个 Schema 节点。这正是 Formily 递归渲染架构的元数据传递通道SchemaField整体由RecursionField驱动每层递归都会重新注入当前节点的 Schema从而保证useFieldSchema()返回的始终是与当前字段匹配的 Schema而不是根 Schema。值得留意的是RecursionField的render()分支RecursionField.tsx会依据fieldSchema.type决定渲染哪类字段模型object→ObjectFieldarray→ArrayFieldvoid→VoidField其他类型 →Field无论走哪个分支SchemaContext.Provider都包裹在最外层因此useFieldSchema对各类字段形态都保持一致的行为。四、签名与返回类型文档给出的签名如下interface useFieldSchema { (): Schema }无参数调用时不需要传入任何参数返回Schema返回formily/json-schema中的Schema类实例。关于Schema的完整字段与方法toJSON、properties、mapProperties等可参考 json-schema 包中的 Schema 类实现。Schema实例上常用的能力包括能力说明schema.toJSON()将 Schema 序列化为纯 JSON 对象便于展示/调试schema.properties获取子字段 Schema 映射是递归渲染的数据基础schema[x-component]读取当前字段声明的渲染组件名schema[x-component-props]读取当前字段声明的组件参数schema[x-decorator]读取当前字段声明的装饰器组件名schema.mapProperties(fn)遍历并映射子字段 Schema见下方测试用例schema.filterProperties(fn)过滤子字段 Schema见下方测试用例五、完整用例解析文档给出了一个可直接运行的完整示例我们在原示例基础上补全了类型标注与注释方便直接复制验证import React from react import { createForm } from formily/core import { FormProvider, createSchemaField, useFieldSchema } from formily/react const form createForm() // 自定义组件在内部读取当前字段的 Schema并渲染为 JSON const Custom () { const schema useFieldSchema() return ( code pre{JSON.stringify(schema.toJSON(), null, 2)}/pre /code ) } // 通过 createSchemaField 把自定义组件注册进 Schema 渲染体系 const SchemaField createSchemaField({ components: { Custom, }, }) export default () ( FormProvider form{form} SchemaField SchemaField.Object namecustom x-componentCustom x-component-props{{ schema: { type: object, properties: { input: { type: string, x-component: Custom, }, }, }, }} / /SchemaField /FormProvider )这个例子演示了完整链路createForm()创建表单实例FormProvider把表单实例提供给整个子树createSchemaField({ components: { Custom } })把自定义组件Custom注册为 Schema 可用的组件SchemaField.Object以 JSON Schema 标记语言JSX 形式声明一个object类型字段并指定x-componentCustom意味着这个节点将由Custom组件渲染渲染到Custom内部时useFieldSchema()返回的就是这个object节点的Schema实例schema.toJSON()将 Schema 序列化为可读的 JSON 并展示。运行后页面会输出当前字段的完整 Schema JSON包含type、x-component、x-component-props等声明信息。注意x-component-props中传入的schema属性只是普通对象数据与useFieldSchema返回的Schema实例是不同的东西——前者是静态配置数据后者是 Formily 解析后的 Schema 模型对象。六、实战深化用 useFieldSchema 驱动 RecursionField 递归渲染useFieldSchema最具价值的应用场景是自定义组件 递归渲染子字段。官方测试 schema.markup.spec.tsx 中给出了大量可参考的真实用法下面是三个典型模式。6.1 获取当前 Schema 并继续递归渲染const CustomObject: React.FC () { const schema useFieldSchema() return ( div {/* 把当前 Schema 交给 RecursionField继续渲染它的子属性 */} RecursionField schema{schema} / /div ) }这种占位壳组件的写法在布局类、容器类自定义组件中非常常见外层组件负责布局如卡片、折叠、网格内部通过RecursionField schema{schema}把子字段继续渲染出来。6.2 只渲染子属性onlyRenderProperties当需要跳过当前字段模型本身、直接渲染它的properties时可以配合useField拿到字段地址并设置onlyRenderPropertiesconst CustomObject2: React.FC () { const field useField() const schema useFieldSchema() return ( div RecursionField name{schema.name} basePath{field.address} schema{schema} onlyRenderProperties / /div ) }对应测试断言schema.markup.spec.tsx中的onlyRenderProperties用例验证使用该写法后内部 Input 仍然正常渲染queryAllByTestId(input).length为 3而仅输出子属性的容器节点有 2 个证明onlyRenderProperties确实只递归子字段、不再额外生成当前字段模型。6.3 映射与过滤子字段mapProperties / filterProperties自定义容器还可以在递归前对子 Schema 做变换或筛选// mapProperties给所有子字段设置默认值 RecursionField schema{schema} mapProperties{(schema) { schema.default 123 return schema }} / // filterProperties按条件过滤子字段 RecursionField schema{schema} filterProperties{(schema) { if (schema[x-component] Input) return false return true }} /对应测试mapProperties、filterProperties用例分别验证了mapProperties后 Input 的 value 变为123filterProperties后 Input 数量由 3 变为 2。这些 API 组合充分体现了读取 Schema → 变换 Schema → 递归渲染的完整开发范式。七、与 useField 的对比什么时候用哪个在 Formily React 自定义组件开发中useFieldSchema与useField经常同时出现但职责不同对比维度useFieldSchemauseField读取内容当前字段的 JSON Schema声明元数据当前字段的字段模型运行时状态返回类型Schema来自formily/json-schemaGeneralField来自formily/core状态响应不响应字段状态变化仅静态 Schema需要配合observer包装组件以响应字段状态变化典型用途读取x-component-props、递归渲染子 Schema读取/修改字段值、校验状态、显隐联动关于useField的详细说明可参考同目录下的 useField.zh-CN.md。实际开发中两者常搭配使用useField取运行态字段如field.address作为递归的basePathuseFieldSchema取 Schema 声明如schema.name、schema.properties。八、常见问题与注意事项返回 null 导致报错SchemaContext默认值为null在SchemaField/RecursionField子树外调用useFieldSchema()会得到null。使用前应确保组件挂在 Schema 渲染树内必要时可做空值兜底。schema.toJSON()只输出 Schema 结构它序列化的是 Schema 声明本身type、properties、x-*等不包含字段当前值、校验状态等运行时信息需要运行时状态请用useField。与x-component-props中静态传入的schema属性区分useFieldSchema()返回的是 Formily 的Schema模型实例带toJSON、mapProperties等方法JSX 标记里通过x-component-props{{ schema: {...} }}传的只是普通对象。Schema 只在渲染层存在useFieldSchema依赖的是渲染层的 Context 注入RecursionField.tsx因此它不适用于非渲染场景如事件回调、Effects 中那些场景应使用formily/json-schema的 Schema 解析 API 或直接读取表单模型的 Schema 数据。总结useFieldSchema是 Formily React 自定义组件开发中读取当前字段 Schema 声明的官方入口签名极简(): Schema底层即useContext(SchemaContext)见 useFieldSchema.tsSchema 由RecursionField在渲染时注入见 RecursionField.tsx因此只能在SchemaField/RecursionField子树内使用最核心的组合用法是与RecursionField配合实现子 Schema 的递归渲染、属性映射与过滤官方测试 schema.markup.spec.tsx 提供了可直接参考的完整范式。掌握useFieldSchema你就能写出真正由 Schema 驱动的高阶自定义组件将 Formily 动态化表单能力发挥到自定义组件层面。赞分享前端UI组件【免费下载链接】formily Cross Device High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/React Native/Vue 2/Vue 3项目地址https://gitcode.com/gh_mirrors/fo/formily点击查看免费下载相关推荐Formily React useField Hook 完全指南在自定义组件中读取字段模型与状态Formily React useField Hook 完全指南在自定义组件中读取字段模型与状态 导读 useField 是 Formily React 体系前端UI组件react-admin useRecordContext 完全指南从 RecordContext 读取当前记录并构建自定义字段react admin useRecordContext 完全指南从 RecordContext 读取当前记录并构建自定义字段 useRecordContex前端UI组件Formik useField() 完全指南在 React 中构建任意自定义字段组件的核心 HookFormik useField 完全指南在 React 中构建任意自定义字段组件的核心 Hook useField 是 Formik 提供的一个 React上一篇【亲测免费】 Filestash 项目教程下一篇CachyOS服务器内核部署指南高并发场景下的性能调优策略创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表