Ant Design Form 表单一个字段是否展示取决于另一个字段的值

更新日期: 2021-07-20 阅读次数: 11562 字数: 593 分类: ReactJS

需求

我想在 Ant Design Pro 管理后台页面中实现这样一个功能:

统一的系统配置项管理

  • 新增配置项时,需要选择配置项类型:例如字符串、图片、富文本
  • 根据字段类型,分别展示不同的对应 Ant Design 组件:例如 Input 输入框,图片上传组件,富文本编辑组件

这就需要根据类型字段,动态地显示不同的字段。

getFieldValue

搜到需要使用 getFieldValue 来获取依赖字段的当前值,以此为依据来判断该显示不同的组件。

用 github 搜到一段示例代码:

https://github.com/SANGET/custom-platform-tool/blob/529a34c2cd0d61010a84f66e911c6cd2cbb5f8b9/packages/provider-app-hub/TableInfo/components/InfoForm.tsx

shouldUpdate

如果只是使用 getFieldsValue 会报错:

Warning: [antd: Form.Item] children of render props only work with shouldUpdate or dependencies.

参考:

https://ant.design/components/form-cn/#shouldUpdate

Form 通过增量更新方式,只更新被修改的字段相关组件以达到性能优化目的。大部分场景下,你只需要编写代码或者与 dependencies 属性配合校验即可。而在某些特定场景,例如修改某个字段值后出现新的字段选项、或者纯粹希望表单任意变化都对某一个区域进行渲染。你可以通过 shouldUpdate 修改 Form.Item 的更新逻辑。当 shouldUpdate 为 true 时,Form 的任意变化都会使该 Form.Item 重新渲染。这对于自定义渲染一些区域十分有帮助:

<Form.Item shouldUpdate={(prevValues, curValues) => prevValues.additional !== curValues.additional}>
  {() => {
    return (
      <Form.Item name="other">
        <Input />
      </Form.Item>
    );
  }}
</Form.Item>

noStyle 并且 Form.Item 不要设置参数

我在外层 Form.Item 上加了 name 和 label,报错:

devScripts.js:6523 Warning: [antd: Form.Item] Do not use name with children of render props since it's not a field.

修正后的代码:

<Form.Item name="Type" label="类型">
  <Select options={options}>
  </Select>
</Form.Item>
<Form.Item
	noStyle
	shouldUpdate={(prevValues, curValues) => prevValues.Type !== curValues.Type }>
	{({ getFieldValue }) =>
		getFieldValue('Type') == 1 && (
			<Form.Item name="title" label="标题" rules={[{ required: true }]}>
				<Input />
			</Form.Item>
		)
	}
</Form.Item>

完整实现

<Form.Item name="Type" label="类型" rules={[{ required: true }]}>
  <Select options={options}>
  </Select>
</Form.Item>
<Form.Item
    noStyle
    shouldUpdate={(prevValues, curValues) => prevValues.Type !== curValues.Type }>
    {({ getFieldValue }) => {
        let fieldType = getFieldValue('Type');
        if (fieldType == 1) {
            return (
                <Form.Item name="Value" label="内容" rules={[{ required: true }]}>
                    <Input />
                </Form.Item>
            )
        } else if (fieldType == 2) {
            return (
                <Form.Item name="Value" label="图片" rules={[{ required: true }]}>
                    <PicturesWall max="1">
                    </PicturesWall>
                </Form.Item>
            )
        } else if (fieldType == 3) {
            return (
                <Form.Item name="Value" label="内容" rules={[{ required: true }]}>
                    <ReactQuill
                        ref={quill}
                        theme="snow"
                        value={content}
                        onChange={setContent}
                        modules={modules}
                    />
                </Form.Item>
            )
        }
    }}
</Form.Item>

tags: Ant Design Pro

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式