这篇文章主要介绍了解决react-connect中使用forwardRef遇到的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
react-connect使用forwardRef遇到的问题
项目场景
之前独立的两个tab, tab1和tab2, 由于需求变更, 要把这两个tab都放到一个tab4下, 变化大概是从图1变为图2
原因
子组件用了使用了connect, 相当于把forwardRef隔离了,导致父组件拿不到想要的方法, 所以需要把forwardRef
透传给使用了connect
的子组件
问题描述
tip: 该文章以下内容中说的子组件指tab1和tab2, 父组件指tab4
tab1和tab2组件都有"更新数据"按钮,将他们合并为tab4里面之后,"更新数据"按钮已经变成了父组件(tab4)的内容, 但是由于按钮的onClick事件中的逻辑太复杂, 所以点击事件没有挪出来重新写到父组件里。
也就是:按钮在父组件中, 按钮的点击事件在子组件里写。
子组件和父组件都是用函数组件 + Hook 写的, 并且子组件中都用了connect, 此时父组件想调用子组件的点击事件方法, 该怎么拿到子组件里的方法呢?
解决方案
tip: 我的项目使用的是umi2
利用Hoc(高阶组件)透传ref
import React, { forwardRef, useImperativeHandle, useState, useEffect } from 'react';
import { connect } from 'dva'
const Children = (props) => {
const { refInstance } = props
const [text, setText] = useState('子组件:Children')
const functionA = () => {
console.log('c2方法')
setText('ref改变了')
}
useImperativeHandle(refInstance, () => ({
functionA,
text,
}))
return (
<div>
{text}
</div>
)}
const newA = connect((state) => {
return {
list: state.list,
}
})(Children)
// 使用Hoc 透传 ref
export default forwardRef((props, ref) => <newA {...props} refInstance={ref} />);
React.forwardRef的使用说明
React.forwardRef
forwardRef实际上就是当父组件需要得到子组件元素时,可以利用forwardRef来实现。
该方法接受一个有额外ref参数的react组件函数,不调用该方法,普通的组件函数是不会获得该参数的。
应用场景
ref 的作用是获取实例,可能是 DOM 实例,也可能是 ClassComponent 的实例。
但问题来了
如果目标组件是一个 FunctionComponent 的话,是没有实例的(PureComponent),此时用 ref 去传递会报错
React.forwardRef 会创建一个React组件,这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中。这种技术并不常见,但在以下两种场景中特别有用:
- 转发 refs 到 DOM 组件
- 在高阶组件中转发 refs
实例:
点击搜索按钮时,让文本输入框处于聚焦状态
1、普通用法:
import React, { Component } from 'react'
export default class App extends Component {
mytext=null
render() {
return (
<div>
<button type="button" onClick={()=>{
console.log(this.mytext);
this.mytext.current.focus()
this.mytext.current.value="2222"
}}>获取焦点</button>
<Child callback={(el)=>{
console.log(el);、
//el是临时变量,用全局的去接这个值
this.mytext=el
//console.log(el.current);
}}/>
</div>
)
}
}
class Child extends Component {
mytext = React.createRef();
//组件渲染完了执行
componentDidMount() {
this.props.callback(this.mytext);
}
render() {
return (
<div style={{background:"yellow"}}>
<input defaultValue="1111" ref={this.mytext}></input>
</div>
);
}
}
2、使用forwardRef
import React, { Component,forwardRef } from 'react'
export default class App_forwardRef extends Component {
mytext=React.createRef()
render() {
return (
<div>
<button type="button" onClick={()=>{
console.log(this.mytext);
this.mytext.current.value="2222"
}}>获取焦点</button>
<Child ref={this.mytext}/>
</div>
)
}
}
//这里Child是函数式组件
const Child=forwardRef((props,ref)=>{
return (
<div>
<input defaultValue="11111" ref={ref}></input>
</div>
);
})
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程学习网。
本文标题为:解决react-connect中使用forwardRef遇到的问题
基础教程推荐
- 分页技术原理与实现之无刷新的Ajax分页技术(三) 2023-01-20
- 解决ajax的delete、put方法接收不到参数的问题方法 2023-02-23
- 关于 css:WebKit (iPad) CSS3: 背景过渡闪烁 2022-09-21
- ECSHOP中实现ajax弹窗登录功能 2023-01-31
- 深入浅析Jsonp解决ajax跨域问题 2022-12-28
- vue的 Mixins (混入) 2023-10-08
- ExtJS 3.x DateField menuListeners 显示/隐藏 2022-09-15
- 第7天:CSS入门 2022-11-04
- 基于bootstrap的上传插件fileinput实现ajax异步上传功能(支持多文件上传预览拖拽) 2023-02-01
- Vue+WebSocket实现在线聊天 2023-10-08