react 父子组件通信(class组件、hooks组件)

React-组件间通信onRef方法

当在子组件中调用onRef函数时,正在调用从父组件传递的函数。this.props.onRef(this)这里的参数指向子组件本身,父组件接收该引用作为第一个参数:onRef = {ref =>(this.child = ref)} 然后它使用this.child保存引用。之后,可以在父组件内访问整个子组件实例,并且可以调用子组件函数。

组件间通信除了props外还有onRef方法,不过React官方文档建议不要过度依赖ref。

react 文档说明

1、父子组件都为Class组件
// 父组件
import React, {Component} from 'react';
import Child form "./Child"
export default class Parent extends Component {
	onRef = (ref) => {
        this.child = ref
    }
    click = (e) => {
        this.child.getData()
    }
    render() {
        return(
            <div>
                <Child onRef={this.onRef} />
                <button onClick={this.click} >调用子组件</button>
            </div>
        )
    }
}

// 子组件
class default Child extends Component {    
   componentDidMount(){
       //必须在这里声明,所以 ref 回调可以引用它    
       this.props.onRef(this)
    }
    getData = () => {
		// TODO
	)
    render() {
        return (
	        <div>
	        // TODO
			</div>
		)
    }
}
2、父组件为Class组件,子组件为Hooks 组件
// 父组件
import React from "react";
export default class Parent extends React.Component {
  constructor(props) {
    super(props)
  }

  handleChildMethod = () => {
    this.refChild.onChild()
  }
  // 获取绑定子组件
  onRef (ref) {
    this.refChild = ref
  }
  render() {
    return (
      <div>
        <Child
          onRef={(ref) => this.onRef(ref)}
        ></Child>
        <Button onClick={this.handleChildMethod}>调用子组件</Button>
      </div>
    )
  }
}

// Hooks 子组件
import React, {useImperativeHandle} from "react";
const Child = (props) => {
  const [form] = Form.useForm();
  const {} = props
  //正常情况下 ref 是不能挂在到函数组件上的,因为函数组件没有实例,
  // 但是 useImperativeHandle 为我们提供了一个类似实例的东西。
  // 它帮助我们通过 useImperativeHandle 的第 2 个参数,所返回的对象的内容挂载到 父组件的 ref.current 上。
  useImperativeHandle(props.onRef, () => ({
    // onChild 就是暴露给父组件的方法
    onChild: () => {
      return form.getFieldsValue()
    }
  }))
  const onReset = () => {
    form.resetFields();
  };
  const onFinish = (values) => {
    console.log('Success:', values);
  };
  const onFinishFailed = (errorInfo) => {
    console.log('Failed:', errorInfo);
  };

  return(
    <div>
      <Form
        name={'formName'}
        layout="inline"
        autoComplete="off"
        form={form}
        initialValues={{}}
        onFinish={onFinish}
        onFinishFailed={onFinishFailed}
      >
          <Form.Item label="姓名" name="name">
            <Input allowClear placeholder="请输入"/>
          </Form.Item>
          <Form.Item>
            <Button type="default" onClick={onReset} >清空</Button>
          </Form.Item>
      </Form>
    </div>
  )
}
3、父子组件都为Hooks
// 父组件
import {useRef} from 'react';
import ChildRef from './ChildRef'
const Parent = () => {
    const child = useRef();
    const updateChildState = () => {
	   // 组件暴露给父组件的方法
	   console.log(child.current.getVal());
	   child.current.changeVal(100)
	}
    return (
        <>
            <ChildRef ref={child} />
            <button onClick={updateChildState}>触发子组件方法</button>
        </>
    )
}

import React, { useImperativeHandle, forwardRef } from "react"
const Child = (props, ref) => {
  const [count, setCount] = useState(0);
  useImperativeHandle(ref, () => ({ // 暴露给父组件的方法
    getVal,
    changeVal
  }))

  const changeVal = (val) => {
    setCount(val)
  }
  const getVal = () => {
    return count
  }
  return (
    <div>我是子组件{count}</div>
  )
}
// forwardRef实际上就是当父组件需要得到子组件元素时,可以利用forwardRef来实现
const ChildRef = forwardRef(Child)

4、父组件为Hooks ,子组件为Class

// 父组件
const Parent = () => {
  let refChild = {};
  const handleChildMethod = () => {
    // 调用子组件方法
    refChild.setValue(1000);
  }
  return(
    <div>
      <h2>我是父组件</h2>
      <Button onClick={handleChildMethod}>调用子组件</Button>

      <Child onRef={ref => refChild = ref} ></Child>
    </div>
  )
}


// 子组件
export default class Child extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 0
    }
  }
  componentDidMount() {
    this.props.onRef && this.props.onRef(this);
  }
  setValue = (value) => {
    this.setState({
      value
    })
  }
  render() {
    const {value} = this.state
    return (
      <div>
        <h2>我是子组件 {value}</h2>
      </div>
    )
  }
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值