React实现父组件调用子组件的两种写法

 更新时间:2024年04月19日 09:23:20   作者:双子座434  
react通信分很多种,比如:父子通信,兄弟通信等等,这里我们就简单说一下父子通信,父子通信分为:父组件调用子组件里面的方法;子组件调用子组件里面的方法,这里我们着重说一下父组件调用子组件,需要的朋友可以参考下

前言

react通信分很多种,比如:父子通信,兄弟通信等等。这里我们就简单说一下父子通信,父子通信分为:父组件调用子组件里面的方法;子组件调用子组件里面的方法。子调父一个porps就可以解决了,这里我们着重说一下父组件调用子组件。废话不多说,直接上代码:

函数式写法:

方法一:

child.js

import React, { useImperativeHandle, forwardRef } from "react";
 
function Child(props, ref) {
  useImperativeHandle(ref, () => {
    return {
      onClick: handleClick,
    }
  });
 
  const handleClick = () => {
    alert('点击了');
  }
 
  return (
    <button>我是按钮</button>
  )
}
 
export default forwardRef(Child);

index.js

import React, { useRef } from "react";
import Child from './child';
 
function Calling() {
  const nRef = useRef();
 
  const handleClick = () => {
    nRef.current.onClick();
  }
 
  return (
    <div>
      <button onClick={handleClick}>点击后调用子组件</button>
      <Child ref={nRef} />
    </div>
  )
}
 
export default Calling;

父调子通过ref,简单来说:使用钩子函数将子组件自定义的方法绑定到ref.current上面。这里用到了三个钩子:useRef、useImperativeHandle, forwardRef。

1.useRef:父组件使用useRef通过参数(这里的参数命名必须为ref)传递给子组件

2.useImperativeHandle:将子组件自定义的函数添加到父组件的ref上,注意这里,第一个参数为ref,第二个参数为对象(也就是父组件中调用的方法或者要取得属性或者值)。

3.forwardRef:将引用的ref传递给子组件,这时子组件接收到的第一个参数是porps,第二个参数是ref。

上面因为传递给子组件的参数为ref关键字,所以子组件里必须要有接收的方法。

方法二:

child.js

import React from "react";
 
function Child(props) {
  const handleClick = () => {
    alert('点击了');
  }
 
  props.nref = {
    onClick: handleClick,
  }
 
  return (
    <button>我是按钮</button>
  )
}
 
export default Child;

index.js

import React from "react";
import Child from './child';
 
function Calling() {
  const nRef = {};
 
  const handleClick = () => {
    nRef.onClick();
  }
 
  return (
    <div>
      <button onClick={handleClick}>点击后调用子组件</button>
      <Child nref={nRef} />
    </div>
  )
}
 
export default Calling;

index.js(解法二)

import React, { useRef } from "react";
import Child from './child';
 
function Calling() {
  const nRef = useRef();
 
  const handleClick = () => {
    nRef.onClick();
  }
 
  return (
    <div>
      <button onClick={handleClick}>点击后调用子组件</button>
      <Child nref={nRef} />
    </div>
  )
}
 
export default Calling;

大家这里注意看方法二的两个index.js文件差异性,无非就是将空对象换成了useRef,为什么要这样写呢,这样写有什么优点吗?当代码量一样的时候,大家就应该思考一件事情:性能。当然,哪个性能好就选择哪个,我对方法二的这两个index文件做了一下对比(实际上就是空对象和useRef的比较),空对象就不用解释过多了:引用类型...;我们着重解释一下useRef:可以帮我们缓存数据,返回一个ref对象,里面的ref.current是用来存储数据的,返回的ref对象不会被重新创建(言外之意就是他爸爸无论渲染多少次,这个对象指向地址永远只有最原始的那个),这里值的变化不会引起组件的重新render,组件不会因为状态的更新而更新(也就是说,组件状态改变了,这里可以保存改变的状态),如果只想要保存状态,不影响视图更新,并且可以同步获取和更新状态的话,建议使用useRef。

大家想一想,如果他爷爷不断渲染,使用 const nRef = {};是不是就会不断的给nRef赋新的地址,之前的地址只有经过一段时间的不使用才会被垃圾回收机制(不懂垃圾回收机制的去翻翻哈)释放掉;而useRef无论他爷爷渲染多少遍,它的地址最终只有一个。

类组件写法:

方法一:

child.js

import React , { Component } from "react"
 
class Child extends Component {
	handleClick = () => {
           alert('点击了');
        }
 
	render(){
		return (<div>子组件</div>);
	}
}

index.js

class Parent extends Component {
	constructor(props) {
	    super(props);
	 	this.Child = React.createRef();
	}
 
	handleOnClick = ()=>{
		this.Child.current.handleClick();
	}
	render(){
		return (<div>
			<button onClick={this.handleOnClick}>click</button>
			<Child ref={this.Child}></Child>	
		</div>);
	}
}

方法二:

child.js

import React , { Component } from "react"
 
class Child extends Component {
        componentDidMount(){
           this.props.onRef && this.props.onRef(this);
	}
 
	handleClick = () => {
           alert('点击了');
        }
 
	render(){
		return (<div>子组件</div>);
	}
}

index.js

class Parent extends Component {
	handleOnClick = ()=>{
		this.Child.current.handleClick();
	}
 
	render(){
		return (<div>
			<button onClick={this.handleOnClick}>click</button>
			<Child onRef={ data => this.Child = data }></Child>	
		</div>);
	}
}

对比一下类组件的两个方法:

方法一:简单易懂,缺点就是:如果子组件中嵌套了高阶组件,那么就无法指向真实的子组件

方法二:写法更简单易懂,粗暴,缺点就是:需要自定义props属性

这里其实还有一个方法三,思路:大家可以利用高阶组件+反向继承实现。

到此这篇关于React实现父组件调用子组件的两种写法的文章就介绍到这了,更多相关React父调子内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React 中使用 react-i18next 国际化的过程(react-i18next 的基本用法)

    React 中使用 react-i18next 国际化的过程(react-i18next 的基本用法)

    i18next 是一款强大的国际化框架,react-i18next 是基于 i18next 适用于 React 的框架,本文介绍了 react-i18next 的基本用法,如果更特殊的需求,文章开头的官方地址可以找到答案
    2023-01-01
  • react PropTypes校验传递的值操作示例

    react PropTypes校验传递的值操作示例

    这篇文章主要介绍了react PropTypes校验传递的值操作,结合实例形式分析了react PropTypes针对传递的值进行校验操作相关实现技巧,需要的朋友可以参考下
    2020-04-04
  • React实现类似于Vue中的插槽的项目实践

    React实现类似于Vue中的插槽的项目实践

    本文主要介绍了React实现类似于Vue中的插槽的项目实践,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • React 中在 map() 中使用条件跳出map的方法

    React 中在 map() 中使用条件跳出map的方法

    这篇文章主要介绍了React 中在 map() 中使用条件跳出map的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • react中通过props实现父子组件间通信的使用示例

    react中通过props实现父子组件间通信的使用示例

    在React中,父组件可以通过props属性向子组件传递数据,子组件可以通过props属性接收父组件传递过来的数据,本文就来介绍一下如何实现,感兴趣的可以了解一下
    2023-10-10
  • ReactNative列表ListView的用法

    ReactNative列表ListView的用法

    本篇文章主要介绍了ReactNative列表ListView的用法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • 详解React 条件渲染

    详解React 条件渲染

    这篇文章主要介绍了React 条件渲染的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • 使用react完成点击返回顶部操作

    使用react完成点击返回顶部操作

    本文主要介绍了使用react完成点击返回顶部操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • React Native中的RefreshContorl下拉刷新使用

    React Native中的RefreshContorl下拉刷新使用

    本篇文章主要介绍了React Native中的RefreshContorl下拉刷新使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • 一文掌握React 组件树遍历技巧

    一文掌握React 组件树遍历技巧

    这篇文章主要为大家介绍了React 组件树遍历技巧的掌握,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04

最新评论