React useImperativeHandle Hook 90% 前端都不知道转发多个 Refs

我报名了Goldstone Project Phase 1 Challenge——瓜分100,000奖池,这是我的第13篇文章, 点击查看活动详情

为什么ref不属于props,而是需要forwardRef呢?

当我们有一个非常简单的表单组件时,伪代码如下:

 常量形式 = () => {  
 返回<表格>  
 <标签为=“名称”></ label >  
 < 输入类型 = “文本” id = “名称” ></ input >  
 <按钮> 提交</ button >  
 </ form >  
 }  
 复制代码

我想直接从外面获取按钮的DOM引用,怎么办?

理想情况下,我们传递一个 ref 属性。

 常量页 = () => {  
 常量 buttonRef = useRef()  
 返回 < 表单引用 = {buttonRef} />  
 }  
 复制代码

然后在Form组件中接收并绑定。

 常量形式 = ( { ref }) => {  
 返回<表格>  
 <标签为=“名称”></ label >  
 < 输入类型 = “文本” id = “名称” ></ input >  
 <button ref = {ref} > 提交</ button >  
 </ form >  
 }  
 复制代码

但不幸的是,React 并没有这样做。

相应地,React 发明了 forwardRef,这使得代码难以阅读。

 const Form = forwardRef( ( props, ref ) => {  
 返回<表格>  
 <标签为=“名称”></ label >  
 < 输入类型 = “文本” id = “名称” ></ input >  
 <button ref = {ref} > 提交</ button >  
 </ form >  
 })  
 复制代码

为什么要用这种方式?因为 ref 不仅仅是一个 DOM 节点引用,它的作用是“一个不会被重新渲染的状态”。

为什么 ref 不是 refs?

接下来,我的需求发生了变化,我需要获取输入的DOM引用,我该怎么做呢?

最简单的方法是将 ref 绑定到表单元素,然后使用表单元素的 DOM API 来获取子元素。

但这似乎很不React。

当然有一种方法可以传递 ref 一个对象。

像这样:

 常量页 = () => {  
 常量 buttonRef = useRef()  
 常量 inputRef = useRef()  
 return < Form ref = {{ buttonRef , inputRef }} />  
 }  
 复制代码

那么子组件的代码是这样写的:

 const Form = forwardRef( ( props, ref ) => {  
 返回<表格>  
 <标签为=“名称”></ label >  
 < 输入参考 = {ref.inputRef} 类型 = “文本” id = “名称” ></ input >  
 <button ref = {ref.buttonRef} > 提交</ button >  
 </ form >  
 })  
 复制代码

但这又不适用于 TypeScript。

为什么?因为 ref 的类型应该是回调或者具有当前属性的对象。

不过其实只要把ref改成refs就行了,没有那么麻烦。

React 开发团队对此没有任何解释,我认为这是一个设计错误。

什么是 useImperativeHandle Hooks?

我相信大多数 React 工程师都没有接触过这个 API。

它是干什么用的?在进行命令式编程时似乎使用字面意思。 React 官方的说法是当需要暴露给父组件的 DOM 实例时才需要用到,一般用 forwardRef。

如何使用这个 Hooks?很简单。

父组件没有改变,仍然传递一个 ref。

 常量页 = () => {  
 常量 ref = useRef()  
 返回 < 表单 ref = {ref} />  
 }  
 复制代码

子组件即将发生一些变化。

 常量形式 = ( { ref }) => {  
 常量 labelRef = useRef();  
 常量 inputRef = useRef();  
 常量 buttonRef = useRef();  
 useImperativeHandle(ref, () => ({  
 获取标签(){  
 返回标签参考。当前的;  
 },  
 获取输入(){  
 返回输入参考。当前的;  
 },  
 获取按钮(){  
 返回按钮参考。当前的;  
 },  
 }))  
 返回<表格>  
 < 标签参考 = {labelRef} for = "名称" ></ label >  
 < 输入参考 = {inputRef} 类型 = “文本” id = “名称” ></ input >  
 <button ref = {buttonRef} > 提交</ button >  
 </ form >  
 }  
 复制代码

在父组件中访问子组件的 DOM 实例时:

 参考。当前的。输入  
 参考。当前的。按钮  
 复制代码

总结

如您所见,React 在设计上并不理想。它也有很多难以理解的东西。

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议。转载请附上原文出处链接和本声明。

这篇文章的链接: https://homecpp.art/2923/10473/2041

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/39048/39562411

posted @   哈哈哈来了啊啊啊  阅读(113)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示