antd Form.Item 只接受一个 child
antd Form.Item accepts only one child
我创建了一些 Fiddle 来说明这个问题:https://stackblitz.com/edit/react-avejvc-mmhqda?file=index.js
此表格有效:
<Form initialValues={{ surname: 'Mouse'}}>
<Form.Item name="surname">
<Input />
</Form.Item>
</Form>
此表格没有:
<Form initialValues={{ surname: 'Mouse'}}>
<Form.Item name="surname">
<Input />
{null}
</Form.Item>
</Form>
唯一不同的是第二种形式的Form.Item
有两个children.
这背后有什么意图吗?
如果有人想知道我为什么要问。所以像这样的东西破坏了形式:
<Form.Item name={name}>
{type==="string" && <Input />}
{type==="integer" && <InputNumber />}
</Form.Item>
官方文档here给出了一个使用多个children的例子Form.Item
。
<Form.Item label="Field">
<Form.Item name="field" noStyle><Input /></Form.Item> // that will bind input
<span>description</span>
</Form.Item>
您放入 Form.Item
的内容似乎有问题,即。 {null}
可能不允许。
我找到了解决方案,现在对发生的事情有了更好的了解。
来自文档 (https://ant.design/components/form/#Form.Item):
在被 Form.Item 包装后,名称为 属性,值(或由 valuePropName 定义的其他 属性) onChange(或由其他 属性 定义trigger) props 将添加到表单控件中,表单数据的流向将由 Form
处理
文档中也有一个工作示例,这是codepen:https://codepen.io/pen?&editors=001
const { useState } = React;;
const { Form, Input, Select, Button } = antd;
const { Option } = Select;
const PriceInput = ({ value = {}, onChange }) => {
const [number, setNumber] = useState(0);
const [currency, setCurrency] = useState('rmb');
const triggerChange = (changedValue) => {
onChange?.({
number,
currency,
...value,
...changedValue,
});
};
const onNumberChange = (e) => {
const newNumber = parseInt(e.target.value || '0', 10);
if (Number.isNaN(number)) {
return;
}
if (!('number' in value)) {
setNumber(newNumber);
}
triggerChange({
number: newNumber,
});
};
const onCurrencyChange = (newCurrency) => {
if (!('currency' in value)) {
setCurrency(newCurrency);
}
triggerChange({
currency: newCurrency,
});
};
return (
<span>
<Input
type="text"
value={value.number || number}
onChange={onNumberChange}
style={{
width: 100,
}}
/>
<Select
value={value.currency || currency}
style={{
width: 80,
margin: '0 8px',
}}
onChange={onCurrencyChange}
>
<Option value="rmb">RMB</Option>
<Option value="dollar">Dollar</Option>
</Select>
</span>
);
};
const Demo = () => {
const onFinish = (values) => {
console.log('Received values from form: ', values);
};
const checkPrice = (_, value) => {
if (value.number > 0) {
return Promise.resolve();
}
return Promise.reject(new Error('Price must be greater than zero!'));
};
return (
<Form
name="customized_form_controls"
layout="inline"
onFinish={onFinish}
initialValues={{
price: {
number: 0,
currency: 'rmb',
},
}}
>
<Form.Item
name="price"
label="Price"
rules={[
{
validator: checkPrice,
},
]}
>
<PriceInput />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
};
ReactDOM.render(<Demo />, mountNode);
我创建了一些 Fiddle 来说明这个问题:https://stackblitz.com/edit/react-avejvc-mmhqda?file=index.js
此表格有效:
<Form initialValues={{ surname: 'Mouse'}}>
<Form.Item name="surname">
<Input />
</Form.Item>
</Form>
此表格没有:
<Form initialValues={{ surname: 'Mouse'}}>
<Form.Item name="surname">
<Input />
{null}
</Form.Item>
</Form>
唯一不同的是第二种形式的Form.Item
有两个children.
这背后有什么意图吗?
如果有人想知道我为什么要问。所以像这样的东西破坏了形式:
<Form.Item name={name}>
{type==="string" && <Input />}
{type==="integer" && <InputNumber />}
</Form.Item>
官方文档here给出了一个使用多个children的例子Form.Item
。
<Form.Item label="Field">
<Form.Item name="field" noStyle><Input /></Form.Item> // that will bind input
<span>description</span>
</Form.Item>
您放入 Form.Item
的内容似乎有问题,即。 {null}
可能不允许。
我找到了解决方案,现在对发生的事情有了更好的了解。
来自文档 (https://ant.design/components/form/#Form.Item):
在被 Form.Item 包装后,名称为 属性,值(或由 valuePropName 定义的其他 属性) onChange(或由其他 属性 定义trigger) props 将添加到表单控件中,表单数据的流向将由 Form
处理文档中也有一个工作示例,这是codepen:https://codepen.io/pen?&editors=001
const { useState } = React;;
const { Form, Input, Select, Button } = antd;
const { Option } = Select;
const PriceInput = ({ value = {}, onChange }) => {
const [number, setNumber] = useState(0);
const [currency, setCurrency] = useState('rmb');
const triggerChange = (changedValue) => {
onChange?.({
number,
currency,
...value,
...changedValue,
});
};
const onNumberChange = (e) => {
const newNumber = parseInt(e.target.value || '0', 10);
if (Number.isNaN(number)) {
return;
}
if (!('number' in value)) {
setNumber(newNumber);
}
triggerChange({
number: newNumber,
});
};
const onCurrencyChange = (newCurrency) => {
if (!('currency' in value)) {
setCurrency(newCurrency);
}
triggerChange({
currency: newCurrency,
});
};
return (
<span>
<Input
type="text"
value={value.number || number}
onChange={onNumberChange}
style={{
width: 100,
}}
/>
<Select
value={value.currency || currency}
style={{
width: 80,
margin: '0 8px',
}}
onChange={onCurrencyChange}
>
<Option value="rmb">RMB</Option>
<Option value="dollar">Dollar</Option>
</Select>
</span>
);
};
const Demo = () => {
const onFinish = (values) => {
console.log('Received values from form: ', values);
};
const checkPrice = (_, value) => {
if (value.number > 0) {
return Promise.resolve();
}
return Promise.reject(new Error('Price must be greater than zero!'));
};
return (
<Form
name="customized_form_controls"
layout="inline"
onFinish={onFinish}
initialValues={{
price: {
number: 0,
currency: 'rmb',
},
}}
>
<Form.Item
name="price"
label="Price"
rules={[
{
validator: checkPrice,
},
]}
>
<PriceInput />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
};
ReactDOM.render(<Demo />, mountNode);