React项目开发总结:函数组件传参
函数定义的组件似乎(我是说似乎)在我目前这个初学阶段用的并不多,相比类式组件,函数组件虽然代码简单,但是并不很好得体现类&组件式编程,而且网上的学习资料也少得可怜,,,但是我们开发的时候难免用一些优秀的库,然后会发现:
额,看起来哪怕是一个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里了