Ref 屬性 與 DOM 元素

React, 翻譯文章, 如何在元件中取得 DOM 元素

出處:這篇文章的內容是翻譯自官方文件(Refs and the DOM),然後加上筆者的詮釋。

為什麼需要 ref 屬性?

在 React 的世界裡,父元件(parent components)透過 props 將資料傳遞給 子元件(children components),另外子元件也會在 state 存放一些狀態與資料。但某些情況的時候,我們需要能夠存取自己 render 的 DOM 元素或子元件,例如:

  • 管理聚焦、文字選擇,媒體播放。
  • 觸發動畫
  • 整合第三方的 DOM 函式庫

備註:不要過度使用 ref,例如父元件要控制一個對話框的子元件,與其把 open & close 兩個函式暴露給父元件,不如父元件透過 props 傳遞 isOpen 這個屬性給子元件。

在 DOM 元素裡使用 ref 屬性

以下面這個例子來說,CustomTextInput 這個元件有兩個 HTML 元素,一個輸入框與一個按鈕。當按鈕被按下的時候,我們希望游標可以聚焦在輸入框。

重點就在於按鈕的 callback 函式(focus,第 2 行),要如何能夠存取到輸入框這個 DOM 元件。請注意看第 8 行的地方,我們使用了 ref 這個屬性,在這個屬性裡面我們可以放一個 callback 函式,而在這個函式裡面,我們把輸入框 DOM 元件掛在 textInput 這個變數下,接著我們就可以在 focus 這個函式中,透過 this.textInput 來存取到該元素。

Ref 屬性是如何運作的?

當 React 元件被 mount 起來的時候,ref 裡面設定的 callback 會被呼叫,並且把 DOM 元素當參數傳遞進來,在 React 元件被 unmount 的時候,ref callback 會被再呼叫一次,這次傳遞進來的參數就是 null。(因為該 DOM 元素要被消滅了)

React 元件也適用 ref 屬性

Ref 屬性也適用在 react 元件,讓父元件可以存取到子元件,例如下面的範例:

但前提是子元件必須是 Class 元件,白話文就是宣告的方式必須像下面這樣

class CustomTextInput extends React.Component

如果子元件是 Functional 元件(直接透過 function 建立的 react 元件),那就無法使用。

不要過度使用 ref

當在撰寫元件的時候,如果第一個想法是透過 ref 來達到你要的功能時,建議您停下腳步,謹慎地想一想有沒有更好的方式,state 是不是在恰當的位置。通常有更簡單的解決方式,例如將這個 state 往上提。

在 ref 屬性中使用字串

在觀看別人的程式碼的時候,你可能會看到 ref 屬性裡面塞的是「字串」,例如:

<input type="text" ref="firstname"></input>
<input type="text" ref="lastname"></input>

然後透過 this.refs 來存取

getFullName() {
return this.refs.firstname.value + this.refs.lastname.value;
}

這個 pattern 已經在官網建議不要這樣使用了,首先在某些情境下會發生問題(細節可以看這邊,英文版),另外在 react 未來的版本中,有考慮要移除他。

工商時間

24 小時,React 快速入門

讓你用最短時間,充分體會 React 的脈絡思維