ref
是 React 中用來取得 DOM
節點的一個方法,通常是使用 ref
來處理以下這些行為:
focus
、選擇文字等ref
,因為用這種方式取得 DOM
元素固然方便,但使用過多可能會導致產品程式碼長期維護上的不便。另外還有一點要注意的是,在 function component 中是無法使用 ref
的,因為 function component 沒有 instance
。ref
有兩種方式,分別是使用 React.createRef()
和 回調式 ref
。React.createRef()
是 React 中的一個方法,可以創建 ref
。下面我們透過調用 React.createRef()
創建 ref
並賦給 myRef
變數,再將 myRef
放到標籤本身的 ref
屬性上,這樣就能透過 myRef
取得該標籤。
我們創建的 ref
本身是一個物件,裡面有一個屬性 { current: node }
,這個 current
就是我們要取得的 DOM
節點,在下面的範例中,就是 div
。這個 current
當然也包含了一些 HTML
的屬性,比方範例中透過 innerHTML
取得 HTML
內的內容。
class MyComponent extends React.Component {
// 創建 ref
myRef = React.createRef();
componentDidMount () {
console.log(this.myRef); //訪問 ref 物件
console.log(this.myRef.current); //訪問 DOM 節點
console.log(this.myRef.current.innerHTML); // 訪問 DOM 的 HTML 內容
}
render () {
return <div ref={ this.myRef }>內容</div>
}
}
我們也可以透過回調函數來使用 ref
。下面的範例中,我們透過在 div
上增加 ref
屬性,並利用 ref
的回調函數取得節點,這個回調函數的參數本身就是 DOM
節點。
class MyComponent extends React.Component {
// 創建 ref
myRef = null;
componentDidMount () {
console.log(this.myRef); //直接取得 DOM 節點
console.log(this.myRef.innerHTML); // 訪問 DOM 的 HTML 內容
}
render () {
// 透過 ref 回調函數來取得 DOM 節點
return <div ref={node => this.myRef = node }>內容</div>
}
}
ref
有不少運用方式和時機,其中一個就是像前面提到的,利用 ref
做 focus
的行為。下面的範例中,我們先創建一個 ref
並賦給 textInput
,並放入到 input
標籤的 ref
中,這樣就能取得它的 DOM
,同時我們透過 focusInput
函式去調用 textInput
執行綁定動作,這樣當點擊按鈕時,就會 focus
在 input
上
class UserProfile extends React.Component {
constructor() {
super ();
this.textInput = React.createRef();
this.focusInput = this.focusInput.bind(this);
}
focusInput() {
this.textInput.current.focus();
}
render() {
return (
<div>
<input
type="text"
ref={this.textInput} />
<button onClick={this.focusInput}>click</button>
</div>
);
}
}
我們也可以直接在 component
上面使用 ref
,來取得 component
內的 DOM
,讓元件在 mounting
完之後就自動 focus
,不過這種作法一樣是只能用在 class component 上。React
是在 mounting
的階段去處理 ref
,將 DOM
element
賦到 ref
的 current
屬性中,在 unmounting
時再去清空回 null
狀態。至於 ref
的更新是發生在 componentDidMount
或 componentDidUpdate
之前。
// 在元件中使用 ref 取得 DOM element
class TextInput extends React.Component {
constructor() {
super();
this.textInput = React.createRef();
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
this.textInput.current.focus();
}
render () {
return <div>
<input
type="text"
ref={this.textInput}
/>
<button onClick={this.focusInput}>click</button>
</div>
}
}
class UserProfile extends React.Component {
constructor() {
super();
this.textInput = React.createRef();
}
componentDidMount() {
this.textInput.current.focusTextInput();
}
render() {
// 在 component 上使用 ref,直接去取得 component 內的 DOM 並執行 focus 行為
return (
<div>
<TextInput ref={this.textInput} />
</div>
);
}
}
這一篇主要是整理 ref
的基本用法,除了課程內容外,也有參考官網的說明和範例,因為官網講得更為詳細(也讓我看的頭很痛)。下一篇會透過表單事件處理,來更了解 react 中 event
和 ref
的使用。