Ref的作用:Refs 提供了一種方式,允許我們訪問 DOM 節點或在 render 方法中創建的 React 元素。
什么時候使用:react的狀態態的開發形式,能通過狀態控制的,應該避免盡可能少的使用ref。
一.創建並訪問refs(方法一)
①
創建refs:Refs 是使用 React.createRef()
創建的,並通過 ref
屬性附加到 React 元素。在構造組件時,通常將 Refs 分配給實例屬性,以便可以在整個組件中引用它們。
② 當 ref 被傳遞給 render 中的元素時,對該節點的引用可以在 ref 的 current 屬性中被訪問
class CustomTextInput extends React.Component { constructor(props) { super(props); // 創建一個 ref 來存儲 textInput 的 DOM 元素 this.textInput = React.createRef(); this.focusTextInput = this.focusTextInput.bind(this); } focusTextInput() { // 直接使用原生 API 使 text 輸入框獲得焦點 // 注意:我們通過 "current" 來訪問 DOM 節點 this.textInput.current.focus(); } render() { // 告訴 React 我們想把 <input> ref 關聯到 // 構造器里創建的 `textInput` 上 return ( <div> <input type="text" ref={this.textInput} /> <input type="button" value="Focus the text input" onClick={this.focusTextInput} /> </div> ); } }
注意:!!ref 的值根據節點的類型而有所不同:
- 當 ref 屬性用於 HTML 元素時,構造函數中使用 React.createRef() 創建的 ref 接收底層 DOM 元素作為其 current 屬性。
- 當 ref 屬性用於自定義 class 組件時,ref 對象接收組件的掛載實例作為其 current 屬性。
· 你不能在函數組件上使用 ref 屬性,因為他們沒有實例
二.使用回調refs來設置refs
React 也支持另一種設置 refs 的方式,稱為“回調 refs”。它能助你更精細地控制何時 refs 被設置和解除。
不同於傳遞 createRef() 創建的 ref 屬性,你會傳遞一個函數。這個函數中接受 React 組件實例或 HTML DOM 元素作為參數,以使它們能在其他地方被存儲和訪問。
下面的例子描述了一個通用的范例:使用 ref 回調函數,在實例的屬性中存儲對 DOM 節點的引用。

class CustomTextInput extends React.Component { constructor(props) { super(props); this.textInput = null; this.setTextInputRef = element => { this.textInput = element; }; this.focusTextInput = () => { // 使用原生 DOM API 使 text 輸入框獲得焦點 if (this.textInput) this.textInput.focus(); }; } componentDidMount() { // 組件掛載后,讓文本框自動獲得焦點 this.focusTextInput(); } render() { // 使用 `ref` 的回調函數將 text 輸入框 DOM 節點的引用存儲到 React // 實例上(比如 this.textInput) return ( <div> <input type="text" ref={this.setTextInputRef} /> <input type="button" value="Focus the text input" onClick={this.focusTextInput} /> </div> ); } }
React 將在組件掛載時,會調用 ref 回調函數並傳入 DOM 元素,當卸載時調用它並傳入 null。在 componentDidMount 或 componentDidUpdate 觸發前,React 會保證 refs 一定是最新的。
你可以在組件間傳遞回調形式的 refs,就像你可以傳遞通過 React.createRef() 創建的對象 refs 一樣
function CustomTextInput(props) { return ( <div> <input ref={props.inputRef} /> </div> ); } class Parent extends React.Component { render() { return ( <CustomTextInput inputRef={el => this.inputElement = el} /> ); } }
在上面的例子中,Parent 把它的 refs 回調函數當作 inputRef props 傳遞給了 CustomTextInput,而且 CustomTextInput 把相同的函數作為特殊的 ref 屬性傳遞給了 <input>。結果是,在 Parent 中的 this.inputElement 會被設置為與 CustomTextInput 中的 input 元素相對應的 DOM 節點。
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// 創建一個 ref 來存儲 textInput 的 DOM 元素
this.textInput = React.createRef(); this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
// 直接使用原生 API 使 text 輸入框獲得焦點
// 注意:我們通過 "current" 來訪問 DOM 節點
this.textInput.current.focus(); }
render() {
// 告訴 React 我們想把 <input> ref 關聯到
// 構造器里創建的 `textInput` 上
return (
<div>
<input type="text" ref={this.textInput} /> <input type="button" value="Focus the text input" onClick={this.focusTextInput} />
</div>
);
}
}