react hooks 使用useRef父组件调用子组件方法

使用场景:
一个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
这样就获取到子组件的数据
posted @ 2021-07-04 19:52  潇湘羽西  阅读(2555)  评论(0编辑  收藏  举报