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

文章目录

    需求

    我想在 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>
    

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式