在 objectui#3222 / PR #3289 的实测中发现,未在该 PR 修复(影响面覆盖 ~80 个 widget,属独立重构)。
事实
表单渲染器渲染已注册 widget 时,stripRegisteredFieldProps 剥掉了一批渲染器专用键,但 schema 被剥掉后又显式传了回去(< RegisteredComponent schema={fieldSchema} {...registeredProps} / >,因为约 25 个 widget 读 field || schema 取配置)。
而绝大多数 widget 的写法是:
export function TextField({ value, onChange, field, readonly, ...props }: FieldWidgetComponentProps< string >) {
const { inputType, ...domProps } = props as any;
return < Input {...domProps} … / >; // schema 在 domProps 里
}
schema 没被解构出来,于是原样落到 DOM 上。实测(jsdom,真表单 + 真 widget)的输出:
< input class="…" schema="[object Object]" id="_r_0_-form-item"
aria-describedby="…" aria-invalid="true" type="text" value="" name="t" >
schema="[object Object]" 出现在每一个这样渲染的输入框上。React 不报警(全小写属性会被透传),所以它安静地存在了很久。
为什么值得修
可能的方向(需要拍板,不要直接开工)
- 共享的
toDomProps(props) 助手,在 @object-ui/fields 导出,每个 widget 用它替代裸 ...props 展开。显式、可 grep、可测试;但要改 ~80 个文件。
- 收敛
schema 与 field 本身(注释里说的那件事),让 schema 不再需要被传下去。更根治,但影响读 field || schema 的 ~25 个 widget。
- 什么都不做,只把它记录成已知取舍。
倾向 2 → 1 的顺序,但这是架构判断,应当先定方向。
边界
packages/fields(+ 可能 packages/components/src/renderers/form/)。不动 packages/spec。
关联:objectui#3221(封闭该类型的那一单)、objectui#3222、PR #3289。
在 objectui#3222 / PR #3289 的实测中发现,未在该 PR 修复(影响面覆盖 ~80 个 widget,属独立重构)。
事实
表单渲染器渲染已注册 widget 时,
stripRegisteredFieldProps剥掉了一批渲染器专用键,但schema被剥掉后又显式传了回去(< RegisteredComponent schema={fieldSchema} {...registeredProps} / >,因为约 25 个 widget 读field || schema取配置)。而绝大多数 widget 的写法是:
schema没被解构出来,于是原样落到 DOM 上。实测(jsdom,真表单 + 真 widget)的输出:schema="[object Object]"出现在每一个这样渲染的输入框上。React 不报警(全小写属性会被透传),所以它安静地存在了很久。为什么值得修
[object Object]还意味着一次无意义的String(object)。FieldWidgetComponentProps注释里已经承认的「第二契约」(schema与field承载同一个东西)的可见症状——注释原文说「converging the two is tracked separately」。error,并接上生产者 (#3222) #3289 起error也走同一条路(失败时留下error="T is required",同样无警告)。fix(fields,components): 字段 widget 的校验槽位改用 spec 的error,并接上生产者 (#3222) #3289 有意保留了这个转发——按 widget 类型做白名单会对第三方 widget 重建「声明了但没交付」——但这恰恰说明该收口的地方是 widget 的 DOM 展开,不是宿主的转发。可能的方向(需要拍板,不要直接开工)
toDomProps(props)助手,在@object-ui/fields导出,每个 widget 用它替代裸...props展开。显式、可 grep、可测试;但要改 ~80 个文件。schema与field本身(注释里说的那件事),让schema不再需要被传下去。更根治,但影响读field || schema的 ~25 个 widget。倾向 2 → 1 的顺序,但这是架构判断,应当先定方向。
边界
packages/fields(+ 可能packages/components/src/renderers/form/)。不动packages/spec。关联:objectui#3221(封闭该类型的那一单)、objectui#3222、PR #3289。