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

JsonForms(React+MUI)中CEP渲染器调用API更新字段失败的解决

JsonForms + MUI 中CEP输入框失焦后无法同步更新其他表单字段的问题解决

问题场景

我们在React项目中使用JsonForms结合MUI开发表单,实现了一个CEP(邮政编码)输入渲染器。该渲染器在输入框失焦时会调用API获取对应地址信息,并尝试通过props.handleChange同步更新表单内其他字段(如街道、街区、城市、州)。

以下是CEP渲染器的简化实现代码:

export const cepRender = {
  tester: cepRenderTester,
  renderer: withJsonFormsControlProps((props) => {
    const handleChange = async (event: FocusEvent<HTMLInputElement>) => {
      const cep = event?.target?.value;
      props.handleChange(props?.path, cep);

      if (cep?.replace?.(/\D/g, '')?.length === 8) {
        const response = await client.get(`https://viacep.com.br/ws/${cep}/json/`);
        const { logradouro, bairro, localidade, uf } = response.data;
        props.handleChange('endereco.logradouro', logradouro || '');
        props.handleChange('endereco.bairro', bairro || '');
        props.handleChange('endereco.municipio', localidade || '');
        props.handleChange('endereco.estado', uf || '');
      }
  };

  return (
    <div className='custom-input-container' ref={fieldRef}>
      <TextField
        {...props}
        variant='filled'
        className="input"
        required={props.required}
        defaultValue={props?.data ?? ''}
        inputRef={
          props?.uischema?.options?.mask ? withMask(props.uischema.options.mask) : undefined
        }
        onBlur={handleChange}
        InputProps={{ disableUnderline: true } as Partial<OutlinedInputProps>}
      />
    </div>
  );
}),
}

问题现象

切换到MUI组件库后,调用props.handleChange更新其他字段的数据后,这些字段的显示值并未同步更新。此前未使用MUI时,该功能可以正常工作。

问题原因

MUI的TextField组件使用defaultValue属性时,仅会在组件初始化阶段设置一次输入值,后续数据发生变化时不会触发组件重新渲染。虽然props.handleChange已经正确修改了表单的底层数据,但其他字段的渲染器仍通过defaultValue绑定数据,导致无法感知数据变化并更新显示。

解决方法

将其他字段渲染器中使用的defaultValue属性替换为value属性,让组件能够响应表单数据的变化,实时更新显示内容。

内容的提问来源于stack exchange,提问作者Thiago Dias

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:44:51