Ant Design Form.Item 中使用 Select 组件默认值总是显示数字

发布时间: 2021-06-03 16:52:14 作者: 大象笔记

现象

在 Antd Pro 中使用了 Antd Form 来编辑报修单的进度状态。

但是在选中一条记录,在使用 Select 组件进行编辑时,总是显示状态码,而非状态描述。

看起来是之前遇到过的,select value 的整型与字符串的转换问题。

Warning: children should be Select.Option or Select.OptGroup instead of Option

原始代码:

<Form.Item name="status" label="状态">
  <Select>
	<Option value="1">待处理</Option>
	<Option value="2">处理中</Option>
	<Option value="3">已完成</Option>
  </Select>
</Form.Item>

Chrome Console 中显示警告信息:

Warning: children should be Select.Option or Select.OptGroup instead of Option

vscode 中直接报错:

JSX element class does not support attributes because it does not have a 'props' property.

'Option' cannot be used as a JSX component.
Its instance type 'HTMLOptionElement' is not a valid JSX element.
Type 'HTMLOptionElement' is missing the following properties from type 'ElementClass': render, context, setState, forceUpdate, and 3 more.

按照提示,修改为:

<Form.Item name="status" label="状态">
  <Select>
	<Select.Option value="1">待处理</Select.Option>
	<Select.Option value="2">处理中</Select.Option>
	<Select.Option value="3">已完成</Select.Option>
  </Select>
</Form.Item>

没有报错了,但是,还是只显示 1, 而非状态描述 "待处理"。

解决方法一

在选中要修改的行时,将对应的字段值由整型转换成字符串。

<a
  key="config"
  onClick={() => {
	handleFormVisible(true);
	record.status += ""
	setCurrentRow(record);
  }}
>
  编辑
</a>,

这样 Form 在处理时,初始化值就变成字符串 “1”,于是显示就正常了。

(最佳) 解决方法二

参考:

https://ant.design/components/select-cn/#API

可以看到 select 组件有个 options 属性:

options 数据化配置选项内容,相比 jsx 定义会获得更好的渲染性能 { label, value }[]

何不尝试一下,于是修改了一下:

const options = [
  {
	label: "待处理",
	value: 1,
  },
  {
	label: "处理中",
	value: 2,
  },
  {
	label: "已完成",
	value: 3,
  },
];

...

<Form.Item name="status" label="状态">
  <Select options={options}>
  </Select>
</Form.Item>

这样就能保证 value 是整型,跟服务端返回的类型一致。

测试了一下,果然可以。幸好没有用 ProForm 的方案。

(无效) 尝试 ProComponents ProFormSelect 组件

虽然我很厌恶 ProComponents 这种对低质量代码再进行低质量封装的行为,但是没办法只能硬着头皮试试了。

import { ProFormSelect } from '@ant-design/pro-form';

<ProFormSelect
    name="status"
    label="status"
    valueEnum={{
      1: '未解决',
      3: '已解决',
    }}
    placeholder="Please select a country"
  />

也不行, 还是显示 1。

(无效) 设置 valuePropName

参考:

https://github.com/ant-design/ant-design/issues/5226

I have found that you have to set valuePropName to "option" in the getFieldDecorator options in order for the placeholder text to show, but I can't find any documentation on this, so I wanted to share incase other people have run into the same issue.

{getFieldDecorator('roleList', {
  initialValue: user.roleList || [],
  valuePropName: 'option',
  rules: [
    { required: false, message: 'Assign roles for this user', type: 'array' },
  ],
})(
  <Select mode="multiple" placeholder="Assign roles for this user">
    <Select.Option value="role_admin">Administrator</Select.Option>
    <Select.Option value="role_seller">Seller</Select.Option>
    <Select.Option value="role_customer">Customer</Select.Option>
  </Select>
)}

对应的,我在 Select 组件上添加了 valuePropName 属性,值为 option。

这下可好,啥也不显示了。而且也说不通。

虽然无效,但是了解了有 valuePropName 这个属性的存在,可以自定义非 value 属性的设置,非常好。

我是一名山东烟台的开发者,联系作者