You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 10:57:19