antd从v3升级到v4

# Form适配

# 1. 删除compatible兼容包

移除兼容包

import { Form } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
1
2

将Form放入其他antd引入中。

import { Form, Select, message, Button } from 'antd';
1

# 2. 删除create方法

移除

export default Form.create({})(SetDetainParking);
1

export default 添加类或函数前面

export default class SetDetainParking extends Component {}
1

# 3. onSubmit替换为onFinish

在Form中的onSubmit修改为onFinish,并将自定义的onFinish方法修改为入参values并直接使用。

# 4. Item删除getFieldDecorator

将getFieldDecorator的参数都放入Form.Item中,修改":"为"="连接并添加"{}"。

# 5. 移除props.form

因为form已经从props中移除,所以需要使用form那么采用其他方式。

  • class类型,则在class中添加一个formRef = React.createRef();属性,并在Form中绑定<Form ref={this.formRef}>
  • 函数类型,则在函数中添加一个const [form] = Form.useForm();变量,并在Form中绑定<Form form={form}>

# 6. 设置初始值

除了直接中Form中通过initialValues的方式来设置初始化外,通过setFieldsValue也可以设置。

(1)class类型, 通过formRef = React.createRef();获取form实例设置。

componentDidMount() {
    this.formRef.current.setFieldsValue({
      remark: this.props.data.remark
    });
  }
1
2
3
4
5

(2)函数类型,通过const [form] = Form.useForm();获取form实例设置。

useEffect(() = ()=> {
    cityGetOption({ cityId }).then(res =&gt; {
        if (res.status) return;
        const {
            faceidOption: { open }
        } = res.data;

        form.setFieldsValue({
            faceidOption: { open: open || false }
        });
    });
}, [cityId]);
1
2
3
4
5
6
7
8
9
10
11
12

# 7. Item包含两个组件

当Item中包含了InputNumber和span等其他的时候,那么无法通过name来访问到InputNumber,所以必须将InputNumber用Item包含。即Item包含一个Item和span。

# 8. CheckBox和Switch设置value

使用CheckBox的时候,需要在Item中设置valuePropName="checked,不然无法设置正确的value。

# 9. callback替换

callback需要替换为 return Promise.rejectreturn Promise.resolve()

# 10. 获取value来更新另一个value

当在render中使用一个value来更新另一个value时,那么不能再使用之前的this.props.form.getFieldValue, 而需用通过onValuesChange={onValuesChange}监听所有值的变化,更新state来实现更新另一个value。

const onValuesChange = (changedValues, allValues) =&gt; {
    const operateType = allValues.operateType;
    const costTimeType = typeof operateType === 'undefined' ? 0 : operateType * 1;
    this.setState({
        costTimeType
    })
}
1
2
3
4
5
6
7

# 示范(v3/v4)

async getRefData() {
  const {
    form: { validateFieldsAndScroll },
    dispatch,
    selectedRow,
    onCancel,
    viewType,
  } = this.props;

  return new Promise((resolve, reject) => {
    validateFieldsAndScroll((err, values) => {
      if (err) return reject();
      if (viewType === 'view') {
        onCancel();
        return resolve(values);
      }
      dispatch({
        type: viewType === 'add' ? `${moduleName}/addOne` : `${moduleName}/modOne`,
        payload: {
          ...selectedRow,
          ...values,
          createDate: formatDate(values.createDate),
        },
      }).then(res => {
        const { isSuccess } = res;
        if (isSuccess) {
          onCancel();
          resolve(res);
        }
      });
    });
  });
}
<CommonModal modalOpts={modalProps}>
  <Form {...this.formItemLayout}>
    <Row>
      <Col span={24}>
        <Form.Item label={formatMessage({id: `${moduleName}.title`,defaultMessage: '标题',})} >
          {getFieldDecorator('title', {
            rules: [
              {
                required: true,
                message: getPlaceholder(),
              },
            ],
          })(<Input disabled={disabled} placeholder={getPlaceholder()} />)}
        </Form.Item>
      </Col>
      <Col span={24}>
        <Form.Item label={formatMessage({id: `${moduleName}.statusCd`,defaultMessage: '状态',})}>
          {getFieldDecorator('statusCd', {
            rules: [
              {
                required: true,
                message: getPlaceholder('', 'select'),
              },
            ],
          })(
            <Select
              allowClear
              disabled={disabled}
              style={{ width: '100%' }}
              placeholder={getPlaceholder('', 'select')}
              >
              {STATUS_CD.map(item => {
                return (
                  <Select.Option key={item.value} value={item.value}>
                    {item.label}
                  </Select.Option>
                );
              })}
            </Select>
          )}
        </Form.Item>
      </Col>
    </Row>
  </Form>
</CommonModal>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import { Form, Input, InputNumber, Button, Drawer } from 'antd';
import React from 'react';

const layout = {
  labelCol: { span: 4 },
  wrapperCol: { span: 18 },
};

const validateMessages = {
  required: '${label} is required!',
  types: {
    email: '${label} is not a valid email!',
    number: '${label} is not a valid number!',
  },
  number: {
    range: '${label} must be between ${min} and ${max}',
  },
};

// export const Index = (props) => {
const Index = (props) => {
  const [form] = Form.useForm();

  const handleOk = (e) => {
    // console.log(form.getFieldsValue());
    // form.getFieldsValue();
    return form
      .validateFields()
      .then((values) => {
        console.log('---values--', values);
      })
      .catch((error) => {
        console.log('---error--', error);
      });
  };

  const { visible, onCancel, onOk } = props;
  return (
    <Drawer
      title="选择表单数据"
      getContainer={false}
      width={720}
      onClose={onCancel}
      visible={visible}
      bodyStyle={{ paddingBottom: 80 }}
      footer={
        <div
          style={{
            textAlign: 'right',
          }}
        >
          <Button onClick={onCancel} style={{ marginRight: 8 }}>
            Cancel
          </Button>
          <Button onClick={handleOk} type="primary">
            Submit
          </Button>
        </div>
      }
    >
      <Form
        {...layout}
        name="nest-messages"
        // onFinish={this.onFinish}
        form={form}
        validateMessages={validateMessages}
        scrollToFirstError
        initialValues={{
          name: 'samy',
          email: '123@qq.com',
        }}
        // onFinish={onFinish} 
        // onFinishFailed={onFinishFailed}
      >
        <Form.Item
          name={['user', 'name']}
          label="Name"
          rules={[{ required: true }]}
        >
          <Input />
        </Form.Item>
        <Form.Item
          name={['user', 'email']}
          label="Email"
          rules={[{ type: 'email' }]}
        >
          <Input />
        </Form.Item>
        <Form.Item
          name={['user', 'age']}
          label="Age"
          rules={[{ type: 'number', min: 0, max: 99 }]}
        >
          <InputNumber />
        </Form.Item>
        <Form.Item name={['user', 'website']} label="Website">
          <Input />
        </Form.Item>
        <Form.Item name={['user', 'introduction']} label="Introduction">
          <Input.TextArea />
        </Form.Item>
        {/* <Form.Item wrapperCol={{ ...layout.wrapperCol, offset: 8 }}>
          <Button type="primary" htmlType="submit">
            Submit
          </Button>
        </Form.Item> */}
      </Form>
    </Drawer>
  );
};
export default Index;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

# 参考链接

https://ant.design/docs/react/migration-v4-cn

上次更新: 2022/04/15, 05:41:29
×