formily 自定义组件读取字段 Schema 指南:useFieldSchema 的原理与实战用法
2026/9/23 12:05:24 网站建设 项目流程

formily 自定义组件读取字段 Schema 指南:useFieldSchema 的原理与实战用法

【免费下载链接】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 的@formily/react体系中,useFieldSchema是自定义组件内读取"当前字段 JSON Schema 信息"的核心 Hook。它专门服务于 SchemaField / RecursionField 子树中的自定义组件,让你能在渲染层直接拿到字段的 Schema 定义,进而实现递归渲染、结构感知、动态表单等高级能力。读完本文,你将掌握useFieldSchema的签名、使用边界、底层实现原理,以及基于它的组件递归与结构筛选实战写法。

概述:useFieldSchema 是什么

useFieldSchema@formily/react提供的 React Hook,核心作用是在自定义组件中读取当前字段的 Schema 信息(即声明该字段的 JSON Schema 结构)。它与useField(读取字段模型实例)互补:前者面向"结构定义",后者面向"运行态字段对象"。

该 Hook 有严格的适用范围:只能在SchemaFieldRecursionField的子树中使用。因为其实现完全依赖 React Context(SchemaContext),离开这两个组件挂载的 Provider 子树,Context 值为空,读取不到任何 Schema。

签名与返回值

interface useFieldSchema { (): Schema }
  • 无参数。
  • 返回@formily/json-schema中的Schema类实例,代表当前字段的 Schema 节点。

Schema类的完整 API 可参考 Schema 文档(注:仓库中对应实现位于 packages/json-schema/src/schema.ts)。Schema实例提供了toJSON()mapPropertiesfilterProperties等结构化操作方法,是后续递归渲染的基础。

官方示例:在自定义组件中打印当前字段 Schema

文档给出的完整用例(位于 packages/react/docs/api/hooks/useFieldSchema.md):

import React from 'react' import { createForm } from '@formily/core' import { FormProvider, createSchemaField, useFieldSchema } from '@formily/react' const form = createForm() const Custom = () => { const schema = useFieldSchema() return ( <code> <pre>{JSON.stringify(schema.toJSON(), null, 2)}</pre> </code> ) } const SchemaField = createSchemaField({ components: { Custom, }, }) export default () => ( <FormProvider form={form}> <SchemaField> <SchemaField.Object name="custom" x-component="Custom" x-component-props={{ schema: { type: 'object', properties: { input: { type: 'string', 'x-component': 'Custom', }, }, }, }} /> </SchemaField> </FormProvider> )

要点拆解:

  1. createForm()创建 form 实例,通过FormProvider注入到组件树。
  2. createSchemaField({ components: { Custom } })注册自定义组件Custom,使其能作为x-component被 SchemaField 渲染。
  3. SchemaField.Object声明一个type: 'object'的字段,其x-component指向Custom,并通过x-component-props传入一段嵌套的schema数据。
  4. Custom组件内部调用useFieldSchema(),拿到当前字段(即custom这个 Object 字段)的Schema实例,调用schema.toJSON()序列化为普通 JSON 对象,再格式化输出。

运行后,页面会展示custom字段完整的 Schema 结构(含typenamex-component等)。toJSON()@formily/json-schema的 Schema 类实现,测试中同样通过schema.toJSON()与快照比对来验证 Schema 序列化结果(见 packages/json-schema/src/tests/schema.spec.ts)。

原理剖析:一个 Hook 背后的 Context 机制

useFieldSchema的实现极其精简,完整源码位于 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。该 Context 在 packages/react/src/shared/context.ts 中定义:

export const SchemaContext = createContext<Schema>(null)

同一个文件中还定义了SchemaMarkupContextSchemaExpressionScopeContextSchemaComponentsContextSchemaOptionsContext等一批配套 Context,分别承载 Schema 标记结构、表达式作用域、组件注册表和 SchemaField 工厂选项。ContextCleaner会在渲染流程中清理这些 Context(置为undefined),避免越界污染。

从源码结构可以推断出以下几点使用规则:

  • 只能在 SchemaField / RecursionField 子树内调用:这两个组件负责在渲染阶段向SchemaContext注入当前字段的 Schema 节点;子树之外 Context 值为null,调用会返回空值。
  • 返回的是 Schema 实例而非普通对象:可以直接调用Schema类的方法(如toJSON()mapProperties),而x-component-props里传入的schema只是普通 JSON 数据,需要编译后才能获得实例能力。
  • Hook 与字段位置绑定:每次调用拿到的都是"当前所在位置"的 Schema 节点,同一组件被不同字段复用时,各自读取到各自字段的定义。

该 Hook 通过 packages/react/src/hooks/index.ts 对外统一导出,与useFormuseFielduseParentFormuseFormEffectsuseExpressionScope并列,属于@formily/react标准 Hooks 集合。

实战进阶:用 useFieldSchema 驱动组件递归渲染

useFieldSchema最常见的实战价值是与RecursionField配合,实现"自定义组件内继续递归渲染子 Schema"。这在实现布局容器、表格、分组等复合组件时是刚需。

在 packages/react/src/tests/schema.markup.spec.tsx 的测试用例中,CustomObject组件通过useFieldSchema()取到当前节点 Schema,再把它交给RecursionField继续向下渲染:

const CustomObject: React.FC = () => { const schema = useFieldSchema() return ( <div contenteditable="false">【免费下载链接】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

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询