包装一个 ant-design 表单组件
Wrapping an ant-design form component
我一直在想办法包装一个 ant-design 表单组件。我有几个具有相同选项的 Select
,因此我想创建一个 SelectWrapper
(请参见下面的代码片段)。可惜antd的form好像不喜欢这样,会报错
createBaseForm.js:98 Uncaught TypeError: Cannot read property 'onChange' of undefined
尽管我通过表单道具传递给 Select
。
function ReusableCountrySelect({countries, ...props}) {
return (
<Select
{...props}
>
{
countries.map(c => (
<Select.Option
value={c.id}
key={c.id}
>{c.name}</Select.Option>
))
}
</Select>
);
}
完整示例(传播需要 babel)
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
const mountNode = document.getElementById('root');
import {
Form, Select, Button
} from 'antd';
const FormItem = Form.Item;
const Option = Select.Option;
function ReusableCountrySelect({countries, ...props}) {
return (
<Select
{...props}
>
{
countries.map(c => (
<Select.Option
value={c.id}
key={c.id}
>{c.name}</Select.Option>
))
}
</Select>
);
}
class Demo extends React.Component {
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
}
render() {
const { getFieldDecorator } = this.props.form;
return (
<Form onSubmit={this.handleSubmit}>
<FormItem
label="Select Country"
hasFeedback
>
{getFieldDecorator('select', {
rules: [
{ required: true, message: 'Please select your country!' },
],
})(
<ReusableCountrySelect
countries={[
{name: 'china', id: 'china'},
{name: 'india', id: 'india'},
{name: 'britain', id: 'britain'}
]}
placeholder="Please select a country"
/>
)}
</FormItem>
<FormItem
wrapperCol={{ span: 12, offset: 6 }}
>
<Button type="primary" htmlType="submit">Submit</Button>
</FormItem>
</Form>
);
}
}
const WrappedDemo = Form.create()(Demo);
ReactDOM.render(<WrappedDemo />, mountNode);
克隆 https://github.com/megawac/antd-form-issue 和 npm start
以查看问题
已在 https://github.com/ant-design/ant-design/issues/5700
中解决
Form need controls's ref, but a functional component don't have ref.
解决方案是使用基于 class 的包装器组件代替基于功能的包装器组件。
如何封装antd组件?传播爱心和道具!!!
import { Select as AntSelect} from 'antd';
const Select = (props) => {
return (<AntSelect {...props} >{props.children}</AntSelect>)
}
我一直在想办法包装一个 ant-design 表单组件。我有几个具有相同选项的 Select
,因此我想创建一个 SelectWrapper
(请参见下面的代码片段)。可惜antd的form好像不喜欢这样,会报错
createBaseForm.js:98 Uncaught TypeError: Cannot read property 'onChange' of undefined
尽管我通过表单道具传递给 Select
。
function ReusableCountrySelect({countries, ...props}) {
return (
<Select
{...props}
>
{
countries.map(c => (
<Select.Option
value={c.id}
key={c.id}
>{c.name}</Select.Option>
))
}
</Select>
);
}
完整示例(传播需要 babel)
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
const mountNode = document.getElementById('root');
import {
Form, Select, Button
} from 'antd';
const FormItem = Form.Item;
const Option = Select.Option;
function ReusableCountrySelect({countries, ...props}) {
return (
<Select
{...props}
>
{
countries.map(c => (
<Select.Option
value={c.id}
key={c.id}
>{c.name}</Select.Option>
))
}
</Select>
);
}
class Demo extends React.Component {
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
}
render() {
const { getFieldDecorator } = this.props.form;
return (
<Form onSubmit={this.handleSubmit}>
<FormItem
label="Select Country"
hasFeedback
>
{getFieldDecorator('select', {
rules: [
{ required: true, message: 'Please select your country!' },
],
})(
<ReusableCountrySelect
countries={[
{name: 'china', id: 'china'},
{name: 'india', id: 'india'},
{name: 'britain', id: 'britain'}
]}
placeholder="Please select a country"
/>
)}
</FormItem>
<FormItem
wrapperCol={{ span: 12, offset: 6 }}
>
<Button type="primary" htmlType="submit">Submit</Button>
</FormItem>
</Form>
);
}
}
const WrappedDemo = Form.create()(Demo);
ReactDOM.render(<WrappedDemo />, mountNode);
克隆 https://github.com/megawac/antd-form-issue 和 npm start
以查看问题
已在 https://github.com/ant-design/ant-design/issues/5700
中解决Form need controls's ref, but a functional component don't have ref.
解决方案是使用基于 class 的包装器组件代替基于功能的包装器组件。
如何封装antd组件?传播爱心和道具!!!
import { Select as AntSelect} from 'antd';
const Select = (props) => {
return (<AntSelect {...props} >{props.children}</AntSelect>)
}