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父调子内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于visual studio code + react 开发环境搭建过程

    基于visual studio code + react 开发环境搭建过程

    今天通过本文给大家分享基于visual studio code + react 开发环境搭建过程,本文给大家介绍的非常详细,包括react安装问题及安装 Debugger for Chrome的方法,需要的朋友跟随小编一起看看吧
    2021-07-07
  • React Zustand状态管理库的使用详解

    React Zustand状态管理库的使用详解

    Zustand是一个为React和浏览器环境设计的轻量级状态管理库,由Vercel开发,它特点包括轻量级、易用性、灵活性、可组合性和性能优化,支持多种状态管理模式和中间件,适合中小型项目,Zustand还支持TypeScript,提供类型安全的支持
    2024-09-09
  • react高阶组件经典应用之权限控制详解

    react高阶组件经典应用之权限控制详解

    在React中,高阶组件是重用组件逻辑的一项高级技术。下面这篇文章主要给大家介绍了关于react高阶组件经典应用之权限控制的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-09-09
  • React列表栏及购物车组件使用详解

    React列表栏及购物车组件使用详解

    这篇文章主要为大家详细介绍了React列表栏及购物车组件使用,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • React项目配置prettier和eslint的方法

    React项目配置prettier和eslint的方法

    这篇文章主要介绍了React项目配置prettier和eslint的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • React Router v6路由懒加载的2种方式小结

    React Router v6路由懒加载的2种方式小结

    React Router v6 的路由懒加载有2种实现方式,1是使用react-router自带的 route.lazy,2是使用React自带的 React.lazy,下面我们就来看看它们的具体实现方法吧
    2024-04-04
  • 学习React中ref的两个demo示例

    学习React中ref的两个demo示例

    这篇文章主要介绍了学习React中ref的两个demo示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • react中axios结合后端实现GET和POST请求方式

    react中axios结合后端实现GET和POST请求方式

    这篇文章主要介绍了react中axios结合后端实现GET和POST请求方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • react map使用方法实例详解

    react map使用方法实例详解

    map()方法是在React中常用的数组处理方法之一,可以用于遍历数组、生成组件列表以及进行数据转换等操作,通过合理运用map()方法,可以更灵活地处理和展示数据,下面给大家讲解react map使用方法,感兴趣的朋友一起看看吧
    2023-10-10
  • Taro React自定义TabBar使用useContext解决底部选中异常

    Taro React自定义TabBar使用useContext解决底部选中异常

    这篇文章主要为大家介绍了Taro React底部自定义TabBar使用React useContext解决底部选中异常(需要点两次才能选中的问题)示例详解,有需要的朋友可以借鉴参考下
    2023-08-08

最新评论