React 基礎:Refs 和 DOM 引用之間的關係


React 基礎:Refs 和 DOM 引用之間的關係

前言

這系列是 React 基礎教程(參考 React 官網),記錄了自己入門學習 React 的筆記。不太適合有 React 豐富經驗的同學,但希望看到此文的你,多少都有些收穫。

文章代碼均可在我的碼雲中找到:https://gitee.com/eminoda/react-learn/branches

為了更好的閱讀體驗,可在底下的“瞭解更多”查看原文(我的語雀知識庫)。

Refs 概要

隨著項目發展,肯定會有 React 要和第三方庫(類似 jQuery),或者操作 DOM 的需求。

同時,對於自上而下的 React 數據流中,光靠 props 屬性來控制子組件通常是不夠的。一些特定場景,我們需要一種額外手段來修改子組件的"狀態"。

綜上,需要一個"靠譜"的方式來做這個事情,React 提供了 Refs 這個橋樑 。使我們能夠直接訪問原生的 DOM 節點,或者更好的和 React 元素(組件)進行交互。

官方示意,Refs 可以獲取 class 的組件,以及 HTML 元素 DOM 的引用。函數組件由於沒有 React 實例,所以不能像用於 class 組件那樣來獲取。


獲取 Dom 引用

需求:點擊 button 來觸發 input 元素的聚焦操作。

代碼示例:

React 基礎:Refs 和 DOM 引用之間的關係

說明:

1. 通過 React.createRef() 來創建 React 封裝的 ref 引用對象 inputRefs

2. 將引用對象通過 JSX 語法賦值給 ref 屬性,這樣就和 Html 標籤"扯上關係"了(引用對象即為 Dom 節點)

3. 通過綁定的事件操作,觸發對 Dom 節點的控制(此處是聚焦操作 focus)


這樣,在點擊 button 後,對應的 input 就獲取到了焦點了。


獲取 class 引用

再次強調,Refs 不適用於獲取函數組件的引用。

上面的 BaseInput 已經具備了控制焦點的操作,但可能會有其他需求來控制焦點。

比如下面示例了:父組件加載後,讓 input 聚焦的需求。

代碼示例:

React 基礎:Refs 和 DOM 引用之間的關係

說明:

1. 在構造器,初始化並創建 React 引用對象

2. 將該引用對象通過 JSX 模板,告知 BaseInput 的 ref 屬性

3. 渲染後,就能拿到子組件實例的引用(current 屬性),即能調用到子組件中 focusTextInput 方法

4. 當父組件掛載後,會觸發生命週期 componentDidMount,從而用子組件引用來控制焦點事件


Refs 回調

看下例,比較和上面的用例的不同:

React 基礎:Refs 和 DOM 引用之間的關係

Refs 的回調方式:

1. 去除了 React.createRef() 方法,將引用對象以回調函數的形式來初始化

2. 同時,定義了 element (inputElement )。

3. 當渲染 render 執行後,會對該回調函數進行執行,從而 inputElement 得到賦值。


注意,該引用回調函數的觸發時間點:

React 基礎:Refs 和 DOM 引用之間的關係

對於 class 組件使用:

React 基礎:Refs 和 DOM 引用之間的關係

注意:父組件中的 inputElement 將會是子組件中的元素 element,我們可以拿它來做我們需要的事情。


然後子組件通過 props.inputRefs 來接受此回調方法:

React 基礎:Refs 和 DOM 引用之間的關係


Refs 轉發

如上述 Refs 的使用中,我們已經知道它不支持對函數組件的使用,另外父組件能操控到子組件上的屬性方法(因為整個實例引用都拿到了)


所以為了更好的控制(例如,函數組件),可以使用 ref 轉發。


同樣,參照官網寫了個示例:

React 基礎:Refs 和 DOM 引用之間的關係


代碼上和之前例子做個對比,可以發現:

1. 子組件沒有 React.createRef() 方法了

2. 而且子組件可以不通過 class 組件方式,通過 React.forwardRef 更自由的生成 React 元素


另外,引用對象的 current 的結果也不一樣了:

class 組件獲取子組件的 Refs:

React 基礎:Refs 和 DOM 引用之間的關係


而由 Refs 轉發得到的引用:

React 基礎:Refs 和 DOM 引用之間的關係

前者是子組件實例的引用,後者是對應 Dom 的引用。

總結

Refs 的基本作用就是獲取 DOM 節點和組件的引用,讓我們能更有好的操控“React 元素”。

總比直接拿 document.getElementById 之類的要方便的多,多用於 Form 表單數據操作。


分享到:


相關文章: