【Antd】Antd Form中用自定义组件submit获取不到对应的值

5,239 阅读2分钟

本文完整示例代码点击这里>>

0 异常场景

可能很多人和我一样在使用React + Ant Design开发项目时都曾遇到过这样一个场景:

首先,使用无状态方式自定义城市选择组件CitySelect

// CitySelect.js
import React from 'react'
import { observer } from 'mobx-react'
import { Select } from 'antd'

const { Option } = Select
const CitySelect = observer((props) => {

  return (
    <Select
      showSearch
      allowClear
      style={{ width: 200 }}
      placeholder="Select a city"
      optionFilterProp="children"
      filterOption={(input, option) =>
        option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
      }
    >
      <Option value="SH">上海</Option>
      <Option value="BJ">北京</Option>
      <Option value="SZ">深圳</Option>
      <Option value="XIAN">西安</Option>
    </Select>
  )
})

export default CitySelect


其次,在UserInfoForm中引用自定义组件CitySelect

当点击提交按钮时,因Form没有获取到对应自定义组件的值,从而报错,报错信息如下图:


怎样才能使得Form.Item 包裹一个第三方组件或者自定义组件时,在点击submit时可以获取到对应组件的值呢?

1 解决方案

考虑到在开发中存在class无状态两种组件书写方式,所以本文也会分别从这两种写法出发去寻找对应的解决方案。

1.1 无状态组件

思路:Antd的Form有个设置Form.Item值的方法:props.form.setFieldsValue({ key: value }),我们可以通过给自定义组件传入一个callback函数——> 在自定义组件中将值传给callback——> 通过callback设置Form.Item的值。

实现

UserInfoForm组件中调用自定义组件CitySelect时添加onSelectcallback函数


在自定义组件CitySelect中添加{...props}来接收callback函数


此时再次点击提交按钮时,便可成功获取自定义组件的值。



1.2 class组件

方案一:添加callback

首先,用class方式完成城市选择的组件CitySelectClass,代码如下:

// CitySelectClass.js
import React, { Component } from 'react'
import { Select } from 'antd'

const { Option } = Select

class CitySelectClass extends Component {

  constructor(props) {
    super(props)
  }

  handleSelect = (value) => {
    const { callback } = this.props
    callback(value)
  }

  render() {
    return (
      <Select
        showSearch
        allowClear
        style={{ width: 200 }}
        placeholder="Select a city"
        optionFilterProp="children"
        filterOption={(input, option) =>
          option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
        }
        onSelect={value => this.handleSelect(value)}
      >
        <Option value="SH">上海</Option>
        <Option value="BJ">北京</Option>
        <Option value="SZ">深圳</Option>
        <Option value="XIAN">西安</Option>
      </Select>
    )
  }
}

export default CitySelectClass

UserInfoFormClass组件中调用自定义组件CitySelectClass,并传入回调函数(此方案类似于无状态组件的解决方案)


方案二:this.props.onChange()

定义省份选择组件StateSelectClass

// StateSelectClass.js
import React, { Component } from 'react'
import { Select } from 'antd'

const { Option } = Select

class StateSelectClass extends Component {

  constructor(props) {
    super(props)
  }

  handleSelect = (value) => {
    const { onChange } = this.props
    onChange(value)
  }

  render() {
    return (
      <Select
        showSearch
        allowClear
        style={{ width: 200 }}
        placeholder="Select a state"
        optionFilterProp="children"
        filterOption={(input, option) =>
          option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
        }
        onSelect={value => this.handleSelect(value)}
      >
        <Option value="GZ">广州</Option>
        <Option value="SC">四川</Option>
        <Option value="YN">云南</Option>
        <Option value="SHANXI">陕西</Option>
      </Select>
    )
  }
}

export default StateSelectClass

UserInfoFormClass组件中调用组件StateSelectClass