使用場景:
一個form表單組件,提交按鈕在父組件,點擊時要調用子組件方法獲取子組件數據
child.tsx子組件
主要用到forwardRef傳遞子組件 useImperativeHandle暴露定義的組件方法
import React, { useEffect, forwardRef, useImperativeHandle } from 'react'
import { Form, Input, Select,
Row, Col, DatePicker } from 'antd'
import moment from 'moment'
const { Option } = Select
const { TextArea } = Input
const dateFormat = 'YYYY-MM-DD'
export type productProps = {
infoData?: any
}
const formInput = ({infoData}: productProps, ref: any) => {
const [form] = Form.useForm()
// 暴露組件的方法
useImperativeHandle(ref, () => ({
getForm: () => {
return form
}
}))
useEffect(() => {
if (infoData) {
form.setFieldsValue({...infoData,
establishedTime: moment(infoData.establishedTime)})
}
}, [])
const companyOptions = [
{
companyName: '大米科技有限公司',
id: 1,
companyCode: '1273883',
desc: '這個公司非常棒',
establishedTime: '2020-09-28'
},
{
companyName: '大米科技有限公司2',
id: 2,
companyCode: '2273883',
desc: '這個公司非常棒2',
establishedTime: '2011-09-09'
},
{
companyName: '大米科技有限公司3',
id: 3,
companyCode: '2273883',
desc: '這個公司非常棒3',
establishedTime: '2018-08-18'
}
]
// 根據選擇公司進行回填
const changeCompany = (val, option) => {
console.log(option)
form.setFieldsValue({
...option,
establishedTime: moment(option.establishedtime)
})
}
return (
<div>
<Form
form={form}
layout="vertical"
>
<Row justify="space-between">
<Col span={7}>
<Form.Item
label="公司名稱"
name="companyId"
rules={[{required: true, message: '請選擇公司名稱'}]}>
<Select
showSearch
style={{ width: 200 }}
placeholder="請選擇公司名稱"
onChange={changeCompany}
filterOption={(input, option) =>
option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
>
{companyOptions.map(item =>
<Option
key={item.id}
value={item.id}
companyCode={item.companyCode}
establishedtime={item.establishedTime}
desc={item.desc}
>{item.companyName}</Option>
)}
</Select>
</Form.Item>
</Col>
<Col span={7}>
<Form.Item
label="公司編號"
name="companyCode"
rules={[{required: true, message: '請輸入公司編號'}]}>
<Input disabled placeholder="請輸入公司編號" />
</Form.Item>
</Col>
<Col span={7}>
<Form.Item
label="公司成立時間"
name="establishedTime"
rules={[{required: true, message: '請輸入公司成立時間'}]}>
<DatePicker style={{width: '100%'}} format={dateFormat} />
</Form.Item>
</Col>
</Row>
<Row>
<Col span={24}>
<Form.Item
label="公司描述"
name="desc"
rules={[{required: true, message: '請輸入公司描述'}]}>
<TextArea
placeholder="請輸入公司描述"
autoSize={{ minRows: 2, maxRows: 6 }}
/>
</Form.Item>
</Col>
</Row>
</Form>
</div>
)
}
// 通過forwardRef傳遞
export default forwardRef(formInput)
father.tsx父組件
主要使用useRef創建的ref.通過ref.current.xx調用子組件方法
import React, { useRef } from 'react'
import ProductInfo from '@/components/ProductInfo'
import { Button, Collapse } from 'antd'
import { history } from 'umi'
const { Panel } = Collapse
const formInput = () => {
const childRef = useRef<any>() // 保存
const onSave = async() => {
// 獲取子組件數據
const childForm = childRef.current.getForm()
await childForm.validateFields()
const data = childForm.getFieldsValue()
console.log(data)
}
return (
<div>
<p>
<Button type="primary" onClick={()=>{
history.goBack()
}}>返回 </Button>
</p>
<Collapse defaultActiveKey={['1']}>
<Panel header="公司信息" key="1">
{/*子組件 */}
<ProductInfo ref={childRef} />
</Panel>
<Panel header="產品信息" key="2">
</Panel>
<Panel header="業務信息" key="3">
</Panel>
</Collapse>
<p style={{marginTop: '15px'}}>
<Button type="primary" onClick={onSave}>保存 </Button>
</p>
</div>
)
}
export default formInput
這樣就獲取到子組件的數據
