石家莊做商城網(wǎng)站的公司網(wǎng)站點(diǎn)擊量與排名
forwardRef
【寫在前面】
? 1、ref 的作用是獲取實(shí)例,但由于函數(shù)組件不存在實(shí)例,因此無法通過 ref 獲取函數(shù)組件的實(shí)例引用,而
React.forwardRef
?就是用來解決這個(gè)問題的。? 2、
React.forwardRef
?會(huì)創(chuàng)建一個(gè) React 組件,這個(gè)組件能夠?qū)⑵浣邮盏降?ref 屬性轉(zhuǎn)發(fā)到自己的組件樹。
1.?無法直接使用 ref 引用函數(shù)式組件
在下面的例子中,父組件 Father 想通過 ref
引用子組件 Child,此時(shí)代碼會(huì)報(bào)錯(cuò),因?yàn)楹瘮?shù)式組件沒有實(shí)例對(duì)象,無法被直接引用:
// 父組件
export const Father: React.FC = () => {const childRef = useRef()return (<><h1>Father 父組件</h1><hr /><!-- 下面這行代碼中的 ref 使用不正確,因?yàn)?Child 組件是函數(shù)式組件,無法被直接引用 --><Child ref={childRef} /></>)
}
Child 組件的定義如下:
// 子組件(實(shí)現(xiàn)點(diǎn)擊按鈕,數(shù)值加減的操作)
const Child: React.FC = () => {const [count, setCount] = useState(0)const add = (step: number) => {setCount((prev) => (prev += step))}return (<><h3>Child 子組件 {count}</h3><button onClick={() => add(-1)}>-1</button><button onClick={() => add(1)}>+1</button></>)
}
注意:上面的代碼無法正常運(yùn)行,會(huì)在終端提示如下的 Warning 警告:
Warning:
Function components cannot be given refs. Attempts to access this ref will fail.
Did you mean to use React.forwardRef()?
錯(cuò)誤提示中有解決此問題的關(guān)鍵提示:Did you mean to use React.forwardRef()?
2.?forwardRef 的基本使用
在使用函數(shù)組件時(shí),我們無法直接使用 ref 引用函數(shù)式組件,下面的代碼會(huì)產(chǎn)生報(bào)錯(cuò):
const childRef = useRef(null)
return <Child ref={inputRef} />
因?yàn)槟J(rèn)情況下,你自己的組件不會(huì)暴露它們內(nèi)部 DOM 節(jié)點(diǎn)的 ref。
正確的方法是使用 React.forwardRef()
?把函數(shù)式組件包裝起來
例如 Child 子組件的代碼如下:
// 被包裝的函數(shù)式組件,第一個(gè)參數(shù)是 props,第二個(gè)參數(shù)是轉(zhuǎn)發(fā)過來的 ref
const Child = React.forwardRef((props, ref) => {// 省略子組件內(nèi)部的具體實(shí)現(xiàn)
})
然后,在父組件 Father 中,就可以給子組件 Child 綁定 ref 了:
// 父組件
export const Father: React.FC = () => {const childRef = useRef()// 按鈕的點(diǎn)擊事件處理函數(shù)const onShowRef = () => {console.log(childRef.current)}return (<><h1>Father 父組件</h1>{/* 點(diǎn)擊按鈕,打印 ref 的值 */}<button onClick={onShowRef}>show Ref</button><hr /><Child ref={childRef} /></>)
}
注意:此時(shí)父組件 Father 中獲取到的 ref.current 是
undefined
,因?yàn)樽咏M件 Child 沒有向外暴露任何自己內(nèi)部的東西。