解決react-connect中使用forwardRef遇到的問題
react-connect使用forwardRef遇到的問題
項目場景
之前獨立的兩個tab, tab1和tab2, 由于需求變更, 要把這兩個tab都放到一個tab4下, 變化大概是從圖1變?yōu)閳D2

原因
子組件用了使用了connect, 相當于把forwardRef隔離了,導致父組件拿不到想要的方法, 所以需要把forwardRef 透傳給使用了connect 的子組件
問題描述
tip: 該文章以下內(nèi)容中說的子組件指tab1和tab2, 父組件指tab4
tab1和tab2組件都有"更新數(shù)據(jù)"按鈕,將他們合并為tab4里面之后,"更新數(shù)據(jù)"按鈕已經(jīng)變成了父組件(tab4)的內(nèi)容, 但是由于按鈕的onClick事件中的邏輯太復雜, 所以點擊事件沒有挪出來重新寫到父組件里。
也就是:按鈕在父組件中, 按鈕的點擊事件在子組件里寫。
子組件和父組件都是用函數(shù)組件 + Hook 寫的, 并且子組件中都用了connect, 此時父組件想調(diào)用子組件的點擊事件方法, 該怎么拿到子組件里的方法呢?
解決方案
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的使用說明
forwardRef實際上就是當父組件需要得到子組件元素時,可以利用forwardRef來實現(xiàn)。
該方法接受一個有額外ref參數(shù)的react組件函數(shù),不調(diào)用該方法,普通的組件函數(shù)是不會獲得該參數(shù)的。
應用場景
ref 的作用是獲取實例,可能是 DOM 實例,也可能是 ClassComponent 的實例。
但問題來了
如果目標組件是一個 FunctionComponent 的話,是沒有實例的(PureComponent),此時用 ref 去傳遞會報錯
React.forwardRef 會創(chuàng)建一個React組件,這個組件能夠?qū)⑵浣邮艿?ref 屬性轉發(fā)到其組件樹下的另一個組件中。這種技術并不常見,但在以下兩種場景中特別有用:
- 轉發(fā) refs 到 DOM 組件
- 在高階組件中轉發(fā) refs
實例:
點擊搜索按鈕時,讓文本輸入框處于聚焦狀態(tài)
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();
? //組件渲染完了執(zhí)行
? 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是函數(shù)式組件
const Child=forwardRef((props,ref)=>{
? ? return (
? ? ? <div>
? ? ? ? <input defaultValue="11111" ref={ref}></input>
? ? ? </div>
? ? );
})總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
antd?table動態(tài)修改表格高度的實現(xiàn)
本文主要介紹了antd?table動態(tài)修改表格高度的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-07-07
使用React?Redux實現(xiàn)React組件之間的數(shù)據(jù)共享
在復雜的React應用中,組件之間的數(shù)據(jù)共享是必不可少的,為了解決這個問題,可以使用React?Redux來管理應用的狀態(tài),并實現(xiàn)組件之間的數(shù)據(jù)共享,在本文中,我們將介紹如何使用React?Redux實現(xiàn)Count和Person組件之間的數(shù)據(jù)共享,需要的朋友可以參考下2024-03-03
解決React報錯Property 'X' does not 
這篇文章主要為大家介紹了解決React報錯Property 'X' does not exist on type 'HTMLElement',有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12

