React自定義Hook-useForkRef的具體使用
開篇
使用過 React 技術棧的同學相信都使用過 ref 傳遞給 render 中的元素,而在使用 React 封裝組件時,會有這樣一個場景:
組件將 props.children 作為 render 內容;組件內部會創(chuàng)建 ref 綁定到 props.children 上。
我們知道,元素上只能綁定一個 ref 屬性引用,但對于上面這個場景,props.children 上可能已經存在一個 ref 屬性,而組件內部定義的 ref 也會綁定到 props.children 上。
我們要想一種方式,將兩者的 ref 都可以生效于元素上。
思路
首先我們回顧一下 React 創(chuàng)建 ref 的方式:
- React.createRef():React 16.3 版本提供的 class 創(chuàng)建 ref 方式;
- React.useRef():React Hooks 提供的 函數(shù)組件 創(chuàng)建 ref 方式;
- 回調 Refs:傳遞一個函數(shù)作為元素的 ref 屬性,此函數(shù)接收 React 組件實例或 HTML DOM 元素作為參數(shù)。
綜合考慮,既然 回調 Refs 允許我們傳遞一個函數(shù),并且接收元素實例作為這個函數(shù)的參數(shù),那我們就可以定義一個這樣的函數(shù),在函數(shù)內編寫我們的邏輯來處理 多個 ref 綁定元素實例的場景。(函數(shù)的靈活性)
實現(xiàn)
- 編寫一個函數(shù)(閉包函數(shù)),接收 props.children.ref 和 組件內 ref 作為參數(shù);
- 函數(shù)(閉包函數(shù))需要 return 返回一個函數(shù),這個函數(shù)將作為 回調 Refs 去作用于元素;
- 在 return 的這個函數(shù)中,將函數(shù)參數(shù)(元素引用)綁定到 props.children.ref 和 組件內 ref 上。
上代碼:
function forkRef(refA, refB) {
? return refValue => {
? ? setRef(refA, refValue);
? ? setRef(refB, refValue);
? };
}
function setRef(ref, value) {
? if (typeof ref === 'function') {
? ? ref(value);
? } else if (ref) {
? ? ref.current = value;
? }
}在 setRef 中會針對創(chuàng)建 ref 的方式做不同處理,比如:React.createRef 和 React.useRef 創(chuàng)建的 ref 是一個具有 current 屬性的對象。
使用:
const nodeRef = React.useRef(null); // 組件內部的 ref
const handleRef = forkRef(props.children.ref, nodeRef);
const childrenProps = { ref: handleRef };
return React.cloneElement(children, childrenProps);自定義 Hook - useForkRef
在 Hook 函數(shù)組件中,我們可以借助于 React.memo() 優(yōu)化一下 forkRef() 的邏輯,避免每次組件更新時都創(chuàng)建一個新的閉包函數(shù)。
下面我們使用 TS 編寫一個 useForkRef:
import * as React from 'react';
interface MutableRefObject<T> {
? current: T;
}
type Ref<T> = ((instance: T | null) => void) | MutableRefObject<T> | null;
export function setRef(ref: Ref<unknown>, value: unknown) {
? if (typeof ref === 'function') {
? ? ref(value);
? } else if (ref) {
? ? ref.current = value;
? }
}
export default function useForkRef(refA: Ref<unknown>, refB: Ref<unknown>) {
? return React.useMemo(() => {
? ? if (refA == null && refB == null) {
? ? ? return null;
? ? }
? ? return (refValue: unknown) => {
? ? ? setRef(refA, refValue);
? ? ? setRef(refB, refValue);
? ? };
? }, [refA, refB]);
}使用:
const nodeRef = React.useRef<HTMLElement>(null); // 組件內部的 ref
const handleRef = useForkRef(children.ref, nodeRef);
const childrenProps: any = { ref: handleRef };
React.cloneElement(children, childrenProps)到此這篇關于React自定義Hook-useForkRef的具體使用的文章就介紹到這了,更多相關React Hook-useForkRe內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳解React如何使用??useReducer???高階鉤子來管理狀態(tài)
useReducer是React中的一個鉤子,用于替代?useState來管理復雜的狀態(tài)邏輯,本文將詳細介紹如何在React中使用?useReducer高階鉤子來管理狀態(tài),感興趣的可以了解下2025-02-02
React新擴展函數(shù)setState與lazyLoad及hook介紹
這篇文章主要介紹了React新擴展函數(shù)setState與lazyLoad及hook,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2022-12-12
React中常見的TypeScript定義實戰(zhàn)教程
這篇文章主要介紹了React中常見的TypeScript定義實戰(zhàn),本文介紹了Fiber結構,F(xiàn)iber的生成過程,調和過程,以及 render 和 commit 兩大階段,需要的朋友可以參考下2022-10-10

