一、是什麼
Refs
在計算機中稱為彈性檔案系統(英語:Resilient File System,簡稱ReFS)
React
中的 Refs
提供了一種方式,允許我們訪問 DOM
節點或在 render
方法中建立的 React
元素
本質為ReactDOM.render()
返回的元件例項,如果是渲染元件則返回的是元件例項,如果渲染dom
則返回的是具體的dom
節點
二、如何使用
建立ref
的形式有三種:
- 傳入字串,使用時通過 this.refs.傳入的字串的格式獲取對應的元素
- 傳入物件,物件是通過 React.createRef() 方式建立出來,使用時獲取到建立的物件中存在 current 屬性就是對應的元素
- 傳入函式,該函式會在 DOM 被掛載時進行回撥,這個函式會傳入一個 元素物件,可以自己儲存,使用時,直接拿到之前儲存的元素物件即可
- 傳入hook,hook是通過 useRef() 方式建立,使用時通過生成hook物件的 current 屬性就是對應的元素
傳入字串
只需要在對應元素或元件中ref
屬性
class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render() { return <div ref="myref" />; } }
訪問當前節點的方式如下:
this.refs.myref.innerHTML = "hello";
傳入物件
refs
通過React.createRef()
建立,然後將ref
屬性新增到React
元素中,如下:
class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render() { return <div ref={this.myRef} />; } }
當 ref
被傳遞給 render
中的元素時,對該節點的引用可以在 ref
的 current
屬性中訪問
const node = this.myRef.current;
傳入函式
當ref
傳入為一個函式的時候,在渲染過程中,回撥函式引數會傳入一個元素物件,然後通過例項將物件進行儲存
class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render() { return <div ref={element => this.myref = element} />; } }
獲取ref
物件只需要通過先前儲存的物件即可
const node = this.myref
傳入hook
通過useRef
建立一個ref
,整體使用方式與React.createRef
一致
function App(props) { const myref = useRef() return ( <> <div ref={myref}></div> </> ) }
獲取ref
屬性也是通過hook
物件的current
屬性
const node = myref.current;
上述三種情況都是ref
屬性用於原生HTML
元素上,如果ref
設定的元件為一個類元件的時候,ref
物件接收到的是元件的掛載例項
注意的是,不能在函式元件上使用ref
屬性,因為他們並沒有例項
三、應用場景
在某些情況下,我們會通過使用refs
來更新元件,但這種方式並不推薦,更多情況我們是通過props
與state
的方式進行去重新渲染子元素
過多使用refs
,會使元件的例項或者是DOM
結構暴露,違反元件封裝的原則
例如,避免在 Dialog
元件裡暴露 open()
和 close()
方法,最好傳遞 isOpen
屬性
但下面的場景使用refs
非常有用:
- 對Dom元素的焦點控制、內容選擇、控制
- 對Dom元素的內容設定及媒體播放
- 對Dom元素的操作和對元件例項的操作
- 整合第三方 DOM 庫