React:function类型的父子组件如何传参?我来告诉你!

函数定义的组件似乎(我是说似乎)在我目前这个初学阶段用的并不多,相比类式组件,函数组件虽然代码简单,但是并不很好得体现类&组件式编程,而且网上的学习资料也少得可怜,,,但是我们开发的时候难免用一些优秀的库,然后会发现:

在这里插入图片描述
额,看起来哪怕是一个Form表单人家都建议用函数定义的组件呢,(后续会发现像useState和userHistory这种Hook只允许在函数定义的组件里用)

所以这里我对目前试探出来的方案进行一个陈述

子组件调用父组件方法

App.js(类式定义)

import React, {Component} from 'react'
import Child1 from './component/Child1'

export default class App extends Component {

    funcFather1 = () =>{
        console.log("Child1调用本爹了")
    }
    render() {
        return (
        	<div>
                <Child1 funcFather1={this.funcFather1}/>
        	</div>
        )
    }
}

Child.js(函数式定义)

import React from 'react'
// 声明调用参数
const Child1 = (props) => {
    return(
        <div>
        	{/* 由于是函数定义,props是参数直接用就行 */}
            <button onClick={props.funcFather1}>
                我是Child1
            </button>
        </div>
    )
}
// 暴露组件,使其可以被其他组件import
export default Child1

点击按钮,效果如图
在这里插入图片描述

父组件调用子组件的方法

这里推荐结合使用forwardRef和useImperativeHandle函数

由于以前的函数组件不是类,所以很多方面都受限制,state啊,ref啊(函数组件由于没有实例甚至根本不让用ref),props啊,但有了forwardRef后就能像操作类一样操作函数组件了!!

如果觉得无法读懂概念,那么可以做如下理解:本来呢,函数组件由于没有实例,父组件就算声明了ref引用也没用,因为根本没实例给他引,因为一段“函数”并不能给它定义什么this.某属性。但现在,为函数组件量身打造的forwardRef出现了。
它直接返回一个组件,封装的就是自己的参数 —— 子组件函数体。它就像父子之间一个类似缓冲的通道,父组件的引用声明存在它这里,子组件虽然没实例但此时其return的标签里已经可以使用被传递过来的这些引用声明,因为之后当forwardRef相应封装这样的函数体时,从父组件的视角来看,forwardRef给自己返回了一个带ref能用的实例了,打通父子沟通的通道,父组件便可以调用子组件的东西了。

forwardRef((props, ref) => {函数体})
引用传递(Ref forwading)是一种通过组件向子组件自动传递 引用ref 的技术。对于应用者的大多数组件来说没什么作用。但是对于有些重复使用的组件,可能有用。例如某些input组件,需要控制其focus,本来是可以使用ref来控制,但是因为该input已被包裹在组件中,这时就需要使用Ref forward来透过组件获得该input的引用。
作者:pipu
来源:简书

useImperativeHandle(ref, createHandle, [deps])
useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用 ref 这样的命令式代码。useImperativeHandle 应当与 forwardRef 一起使用。
ref:定义 current 对象的 ref createHandle:一个函数,返回值是一个对象,即这个 ref 的 current
对象 [deps]:即依赖列表,当监听的依赖发生变化,useImperativeHandle 才会重新将子组件的实例属性输出到父组件
ref 的 current 属性上,如果为空数组,则不会重新输出。

作者:_Boboy
来源:CSDN

可以参考参考:ref的前世今生

App.js

import React, { useRef } from 'react';
import Child1 from './component/Child1'

const App = (props) => {
  const buttonRef = useRef();

  return (
    <div>
        {/* buttonRef会作为Child1的forwardRef的ref参数,即ref1 */}
        <Child1 ref={buttonRef} />
        {/* 由于forwardRef直接把Child1整个封装好了,buttonRef现在就是个Child1实例,想要调用其方法直接调就行 */}
        <button onClick={() => buttonRef.current.func1()} >调用Child1</button>
    </div>
  )
}

export default App

Child1.js

import React, {forwardRef, useImperativeHandle} from 'react'

// 例如,这里我的函数组件引用了我自定义名为ref1的 来自父组件的引用参数,即buttonRef
const Child1 = forwardRef((props, ref1) => {
    useImperativeHandle(ref1, () => ({
        func1: () => {
            console.log("我是Child1")
        }
    }));
  
    return <div ref={ref1} />
  });
// 暴露组件,使其可以被其他组件import
export default Child1

点击按钮,效果如图在这里插入图片描述
不过呢,,实战开发的话可能并不建议用函数组件,除非迫不得已(例如第一段里所言,AntDesign官方建议用userForm获取表单信息啥的,这种情况复制粘贴会很方便)。。。毕竟要论解决方案,类式组件才是更成熟的一方。

补充一下我的项目框架,组件全放在component里了在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值