我们知道,对于子组件或者节点,如果是class类,存在实例,可以通过 React.createRef() 挂载到节点或者组件上,然后通过 this 获取到该节点或组件。

class RefTest extends React.Component{
constructor(props){
super(props);
this.myRef=React.createRef();
}
componentDidMount(){
console.log(this.myRef.current);
}
render(){
return <input ref={this.myRef}/>
}
}

  

但是在子组件是函数组件的时候,因为函数组件没有实例,所以在正常情况下, ref 是不能挂载函数组件上的。那么此时,我们通过 useImperativeHandle 和 forwardRef 配合就能达到效果。

useImperativeHandle

useImperativeHandle:可以配合 forwardRef 自定义暴露给父组件的实例值。

useImperativeHandle为我们提供了一个类似实例的东西,它帮助我们通过useImperativeHandle 的第二个参数,将所返回的对象的内容挂载到父组件的 ref.current 上.

useImperativeHandle 接收三个参数:

① 第一个参数 ref:接收 forWardRef 传递过来的 ref。
② 第二个参数 createHandle:处理函数,返回值作为暴露给父组件的 ref 对象
③ 第三个参数 deps:依赖项 deps,依赖项更改形成新的 ref 对象。
forwardRef 会创建一个 React 组件,这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中。

下面举一个实际例子,方便大家理解:

// 子组件

const CollectAmountFormItem = forwardRef(({ isDisabled, val, handleChange }: Props, onRef: any) => {

    const [isShow, setIsShow] = useState<boolean>(val == 1); // 是否展示募集资金和剩余募集资金

	// 暴露给父组件的属性
useImperativeHandle(onRef, () => ({
isShow,
setIsShow
})); useEffect(() => {
if (val == 1) setIsShow(true)
else setIsShow(false)
}, [val]) /**
* 是否募集回调
* @param val 下拉框id
* @param option 下拉框对象
*/
const handleSelect = (val: any, option: any) => {
setIsShow(val == 1);
handleChange && handleChange(val, option);
}; return (
<>
<Col xs={20} sm={16} md={12} lg={8} xl={6}>
<Form.Item name="isRaiseMoney" label="是否募集资金" rules={[{ required: true }]}>
<Select placeholder="请选择" disabled={isDisabled} onChange={handleSelect}>
<Select.Option value={1}>是</Select.Option>
<Select.Option value={0}>否</Select.Option>
</Select>
</Form.Item>
</Col>
{
isShow && (
<>
<Col xs={20} sm={16} md={12} lg={8} xl={6}>
<Form.Item name="usedMoney" label="已使用资金" rules={[{ required: isShow }]}>
<InputNumber
formatter={value => `${value}`.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')}
parser={value => `${value}`.replace(/\$\s?|(,*)/g, '')}
style={{width: '100%'}}
precision={2}
disabled
placeholder="自动计算"
/>
</Form.Item>
</Col>
<Col xs={20} sm={16} md={12} lg={8} xl={6}>
<Form.Item name="remainMoney" label="剩余资金" rules={[{ required: isShow }]}>
<InputNumber
formatter={value => `${value}`.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')}
parser={value => `${value}`.replace(/\$\s?|(,*)/g, '')}
style={{width: '100%'}}
precision={2}
disabled
placeholder="自动计算"
/>
</Form.Item>
</Col>
</>
)
}
</>
)
})

  

// 在父组件中使用

// 1、首先引入该子组件
import CollectAmountFormItem from '@/components/CollectAmountFormItem'; // 2、定义一个ref
const collectRef = useRef<any>() // 3、使用
<CollectAmountFormItem isDisabled={isDisable} val={formData.isRaiseMoney} ref={collectRef} handleChange={handleChangeAmount} /> // 然后就可以在父组件中的一些方法中获取子组件暴露出来的方法或值,比如: collectRef.current.setIsShow(false)

  

React-hooks 父组件通过ref获取子组件数据和方法的更多相关文章

  1. react 使用 redux 的时候 用 ref获取子组件的state

    由于 redux是无状态的,所以当我们在子组件中使用了 redux的时候,再父组件中,使用  ref 来获取子组件的state时,发现为一个空对象. 其实这个是有解决方案法的,原因在于 我们使用的 r ...

  2. React 函数式组件的 Ref 和子组件访问(useImperativeHandle)

    引入:如何调用函数式组件内部的方法 对于 React 中需要强制修改子组件的情况,React 提供了 Refs 这种解决办法,使得我们可以操作底层 DOM 元素或者自定的 class 组件实例.除此之 ...

  3. 九、React中的组件、父子组件、React props父组件给子组件传值、子组件给父组件传值、父组件中通过refs获取子组件属性和方法

    一.概述 React中的组件: 解决html 标签构建应用的不足. 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入. [父子组件]:组件的相互调用中,我们把调用者称为父 ...

  4. React Hook父组件获取子组件的数据/函数

    我们知道在react中,常用props实现子组件数据到父组件的传递,但是父组件调用子组件的功能却不常用.文档上说ref其实不是最佳的选择,但是想着偷懒不学redux,在网上找了很多教程,要不就是hoo ...

  5. vue 父组件主动获取子组件的数据和方法 子组件主动获取父组件的数据和方法

    Header.vue <template> <div> <h2>我是头部组件</h2> <button @click="getParen ...

  6. vue父组件中获取子组件中的数据

    <FormItem label="上传头像" prop="image"> <uploadImg :width="150" ...

  7. Vue 父组件主动获取子组件的值,子组件主动获取父组件的值

    父组件主动获取子组件的值 1. 在调用子组件的时候定义一个ref-> ref="header"2. 在父组件中通过this.$refs.header.属性,调用子组件的属性, ...

  8. Vee-validate 父组件获取子组件表单校验结果

    vee-validate 是为 Vue.js 量身打造的表单校验框架,允许您校验输入的内容并显示对应的错误提示信息.它内置了很多常见的校验规则,可以组合使用多种校验规则,大部分场景只需要配置就能实现开 ...

  9. vue父组件获取子组件页面的数组 以城市三级联动为例

    父组件调用子组件 <Cselect ref="registerAddress"></Cselect> import Cselect from '../../ ...

  10. vue.js 父组件主动获取子组件的数据和方法、子组件主动获取父组件的数据和方法

    父组件主动获取子组件的数据和方法 1.调用子组件的时候 定义一个ref <headerchild ref="headerChild"></headerchild& ...

随机推荐

  1. 后台运行&和nohup使用

    这里首先先介绍一下 ctrl+z bg fg jobs 命令 下面为了观察效果,test1.sh脚本不停的输出hello ctrl + z ,会使一个正在运行的进程挂起(暂停)到后台,而且执行jobs ...

  2. 生产环境Java应用服务内存泄漏分析与解决

    有个生产环境CRM业务应用服务,情况有些奇怪,监控数据显示内存异常.内存使用率99.%多.通过生产监控看板发现,CRM内存超配或内存泄漏的现象,下面分析一下这个问题过程记录. 服务器配置情况: 生产服 ...

  3. 痞子衡嵌入式:我拿到了CSDN博客专家实体证书

    「CSDN」作为中国最具人气的专业 IT 社区,一直是广大 IT 技术博主的主选阵地.这些年 CSDN 在知识付费领域的探索也远远超过其它平台,大家(尤其是创作型博主)对 CSDN 的认可度也越来越高 ...

  4. svn提交规范

    本文档参考了Git提交规范,旨在规范使用SVN进行代码版本管理时的提交操作. 提交前的准备 1. 检查代码 在提交代码前,请先进行必要的代码检查,确保代码的正确性.可读性和可维护性.可以使用代码质量管 ...

  5. Rainbond PipeLine插件部署与springboot应用部署实践

    前言:上一篇介绍额rainbond单机部署+单个节点的k8s环境搭建,本篇介绍rainbond5.12新增的pipeline插件的使用 1.Pipeline插件的安装 安装gitlab与gitlab- ...

  6. 续集来了!我让 GPT-4 用 Laf 三分钟写了个完整的待办事项 App

    书接前文,上篇文章我们教大家如何三分钟时间用 Laf 实现一个自己的 ChatGPT. 一觉醒来,GPT-4 已经发布了! GPT-4 实现了真正的多模态,可以把纸笔画的原型直接写出网页代码.读论文时 ...

  7. Java泛型: 主要知识点总结

    Java泛型:主要知识点总结 1 泛型的好处 解决元素存储的安全性问题. 解决获取数据元素时,需要类型强制转换的问题. Java泛型可以保证如果程序在编译时没有发出警告,运行.时就不会产生ClassC ...

  8. MySQL日志机制分析

    进入正题前先简单看看MySQL的逻辑架构,相信我用的着. MySQL的逻辑架构大致可以分为三层: 第一层:处理客户端连接.授权认证,安全校验等. 第二层:服务器server层,负责对SQL解释.分析. ...

  9. 四月十二号java基础知识

    1.面向对象的编程思想是力图使在计算机语言中对事物的描述与现实世界中该事物的本来面目尽可能地一致.2.类(class)和对象(object)是面向对象程序设计方法中最核心的概念3.类是对某一事物的描述 ...

  10. 五月二十六日jdbc算法以及数据库

    1.在PreparedStatement创建SQL对象后,调用preparedStatement()方法时,通过占位符?来按照索引进行SQL语句动态执行通过setString()方法和setInt() ...