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
這樣就獲取到子組件的數據


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM