felix-cao / Blog

A little progress a day makes you a big success!
31 stars 4 forks source link

React 父组件调用子组件的方法 #214

Open felix-cao opened 2 years ago

felix-cao commented 2 years ago

一、Function 组件中使用 Hook

1.1 父组件 Message.js

import * as _ from 'lodash';
import { Modal } from 'antd';
import MessageForm from './MessageForm';
import { IconButton } from "@material-ui/core";
import CloseIcon from '@material-ui/icons/Close';
import React, { useState, useEffect, useRef } from 'react'; // 1. 引入 useRef

function Message(props) {
  const modalRef = useRef(); // 2.使用 useRef hook
  const [isVisible, setIsVisible] = useState(props.visible);
  const onCancel = () => {
    modalRef.current.onCancel(); // 4. 调用子组件暴露出来的onCancel方法
    props.callback({res: false}, 'msg')
  }

  useEffect(() => {
    setIsVisible(props.visible)
  }, [props.visible])

  return (
    <Modal
      footer={null}
      onCancel={onCancel}
      title="Send Message"
      visible={isVisible}
      closeIcon={<IconButton aria-label="close" onClick={onCancel}> <CloseIcon /> </IconButton>}
      >
      <MessageForm {...props} refs={modalRef}/><!-- 3. 绑定到子组件的 refs props中-->
    </Modal>
  )
}

export default Message;

上面的代码,在父组件中注意四步:

1.2 子组件 MessageForm

import React, { useImperativeHandle } from 'react'; // 1. 引入 useImperativeHandle hook
function MessageForm(props) {
  const onCancel = () => {
    form.resetFields();
    setError({err: false, msg: null});
    props.callback({res: false}, 'msg')
  }
  // 此处注意useImperativeHandle方法的的第一个参数是目标元素的ref引用
  useImperativeHandle(props.refs, () => ({
    onCancel,  // 2. 暴露给父组件的方法
  }))

  return (<div>hello world</div>)
}

export default MessageForm;

上面的代码,在子组件中就两步:

Class 组件

未完,待续