发现于 #4799(PR #5122)的实施途中,顺手实测,不在该单半径内,未在该 PR 修。
事实
一个节点同时写了 props 与 properties 两种拼写时,渲染器读哪一个,取决于它用哪条通道读,而两条通道的 alias 优先级正好相反:
- 配置袋通道(
schema.properties.x):element:* 渲染器的 readProps() 是
{ ...schema.props, ...schema.properties } —— properties 赢。
- React prop 通道(组件直接收到的
x prop):SchemaRenderer 在 React.createElement
处先 spread ...componentProps(其中含 evaluation memo 把 properties.* 提升到顶层的那份
拷贝),再 spread ...(evaluatedSchema.props || {}) 覆盖 —— props 赢。
真实 SchemaRenderer 渲染探针实测(节点 props: { content: 'FROM_PROPS' } 与
properties: { content: 'FROM_PROPERTIES' } 同现,同一次渲染里同时读两条通道):
bagRead(properties.content)="FROM_PROPERTIES" reactPropRead(content)="FROM_PROPS"
同一个节点、同一个键,两个答案。哪个上屏纯粹取决于该渲染器碰巧是 readProps() 家族
(elements.tsx / text-input.tsx / record-picker.tsx / data-list.tsx / metadata-viewer.tsx)
还是直接吃 spread 进来的 prop。
#4799 修的是「properties 根本不参与表达式求值」;PR #5122 落地后两边的值都会被求值,
但上面这条优先级分歧是独立的、且 PR #5122 既没有引入也没有改变它(该 PR 显式保持
readProps 的 properties 优先级不变)。因此单列。
为什么值得看一眼
这是 alias 家族(#4795 / #4797 / #4799 / #4786)的同一根问题的另一面:props 被注释明确称作
legacy alias、properties 是规范拼写,但「规范拼写赢」这件事只在一半的读法上成立。按
contract-first(AGENTS.md #0.1),两条通道要么给同一个答案,要么其中一条根本不该存在。
复现
packages/react/src/SchemaRenderer.tsx 的 React.createElement 调用处(spread 顺序)
对照 packages/components/src/renderers/basic/elements.tsx 的 readProps()。上面的读数由一个
临时探针组件取得(同时打印 schema.properties.content 与它自己收到的 content prop),
探针未入库。
备注
未认领,交 PM 分诊定级 —— 触发条件是作者两种拼写同时写,频次未知;但一旦发生,症状是
「换个渲染器同一份 JSON 结果不同」,不容易被归因。
发现于 #4799(PR #5122)的实施途中,顺手实测,不在该单半径内,未在该 PR 修。
事实
一个节点同时写了
props与properties两种拼写时,渲染器读哪一个,取决于它用哪条通道读,而两条通道的 alias 优先级正好相反:schema.properties.x):element:*渲染器的readProps()是{ ...schema.props, ...schema.properties }——properties赢。xprop):SchemaRenderer在React.createElement处先 spread
...componentProps(其中含 evaluation memo 把properties.*提升到顶层的那份拷贝),再 spread
...(evaluatedSchema.props || {})覆盖 ——props赢。真实 SchemaRenderer 渲染探针实测(节点
props: { content: 'FROM_PROPS' }与properties: { content: 'FROM_PROPERTIES' }同现,同一次渲染里同时读两条通道):同一个节点、同一个键,两个答案。哪个上屏纯粹取决于该渲染器碰巧是
readProps()家族(
elements.tsx/text-input.tsx/record-picker.tsx/data-list.tsx/metadata-viewer.tsx)还是直接吃 spread 进来的 prop。
与 #4799 的关系
#4799 修的是「
properties根本不参与表达式求值」;PR #5122 落地后两边的值都会被求值,但上面这条优先级分歧是独立的、且 PR #5122 既没有引入也没有改变它(该 PR 显式保持
readProps的properties优先级不变)。因此单列。为什么值得看一眼
这是 alias 家族(#4795 / #4797 / #4799 / #4786)的同一根问题的另一面:
props被注释明确称作legacy alias、
properties是规范拼写,但「规范拼写赢」这件事只在一半的读法上成立。按contract-first(AGENTS.md #0.1),两条通道要么给同一个答案,要么其中一条根本不该存在。
复现
packages/react/src/SchemaRenderer.tsx的React.createElement调用处(spread 顺序)对照
packages/components/src/renderers/basic/elements.tsx的readProps()。上面的读数由一个临时探针组件取得(同时打印
schema.properties.content与它自己收到的contentprop),探针未入库。
备注
未认领,交 PM 分诊定级 —— 触发条件是作者两种拼写同时写,频次未知;但一旦发生,症状是
「换个渲染器同一份 JSON 结果不同」,不容易被归因。