React JSON Form Schema中onChange时如何动态移除表单字段
解决方案
问题出在你直接修改了原schema对象的属性,再把同一个对象传给状态更新函数——React依赖对象引用的变化识别状态更新,引用没变的话不会触发组件重新渲染,所以表单无法即时更新。
正确的做法是每次生成新的schema副本,再更新状态:
const changingSchema = (formData) => { // 深拷贝原schema,确保生成新的对象引用 const updatedSchema = JSON.parse(JSON.stringify(eventProcessingFormSchema)); if (formData.formData.eventprocessingeventcomstatusidid === 1) { // 将目标字段设为只读 updatedSchema.properties.eventprocessingeventcostidid.readOnly = true; // 如果需要彻底移除字段,替换成下面这行: // delete updatedSchema.properties.eventprocessingeventcostidid; } else { // 其他状态下恢复字段可编辑,避免状态残留 if (updatedSchema.properties.eventprocessingeventcostidid) { delete updatedSchema.properties.eventprocessingeventcostidid.readOnly; } } setEventProcessingUIFormSchema(updatedSchema); };
关键说明
- 必须深拷贝原schema:因为schema是嵌套对象,浅拷贝(比如
{...eventProcessingFormSchema})只会复制顶层属性,嵌套的properties还是原引用,修改后依然无法触发React更新。用JSON.parse(JSON.stringify())是原生的深拷贝方式,也可以用lodash.cloneDeep这类工具函数。 - 处理反向逻辑:记得在条件不满足时恢复字段的可编辑状态,不然切换其他值后字段会一直保持只读。
如果使用的是react-jsonschema-form类库,还可以通过uiSchema结合状态控制只读,写法更简洁:
// 假设你有uiSchema的状态 const [uiSchema, setUiSchema] = useState(initialUiSchema); const changingSchema = (formData) => { const newUiSchema = { ...uiSchema }; if (formData.formData.eventprocessingeventcomstatusidid === 1) { newUiSchema.eventprocessingeventcostidid = { ...newUiSchema.eventprocessingeventcostidid, "ui:readonly": true }; } else { if (newUiSchema.eventprocessingeventcostidid) { delete newUiSchema.eventprocessingeventcostidid["ui:readonly"]; } } setUiSchema(newUiSchema); };
这种方式不需要修改核心schema,只调整UI层面的配置,适配大部分JSON Form库的设计思路。
内容的提问来源于stack exchange,提问作者Gethziyaljoyce
相关产品推荐
相关产品推荐

