Refs 提供了一種方式,容許咱們訪問 DOM 節點或在 render 方法中建立的 React 元素。javascript
什麼時候使用Refshtml
避免使用 refs 來作任何能夠經過聲明式實現來完成的事情。(好比:避免在 Dialog
組件裏暴露 open()
和 close()
方法,最好傳遞 isOpen
屬性。)java
Refs 是使用 React.createRef()
建立的,並經過 ref
屬性附加到 React 元素。在構造組件時,一般將 Refs 分配給實例屬性,以即可以在整個組件中引用它們。node
class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render() { return <div ref={this.myRef} />; } }
當 ref 被傳遞給 render
中的元素時,對該節點的引用能夠在 ref 的 current
屬性中被訪問。react
const node = this.myRef.current;
ref 的值根據節點的類型而有所不一樣:git
ref
屬性用於 HTML 元素時,構造函數中使用 React.createRef()
建立的 ref
接收底層 DOM 元素做爲其 current
屬性。ref
屬性用於自定義 class 組件時,ref
對象接收組件的掛載實例做爲其 current
屬性。ref
屬性,由於他們沒有實例。可是能夠在函數組件內部使用 ref
屬性,只要它指向一個 DOM 元素或 class 組件React 會在組件掛載時給 current
屬性傳入 DOM 元素,並在組件卸載時傳入 null
值。ref
會在 componentDidMount
或 componentDidUpdate
生命週期鉤子觸發前更新。 github
在極少數狀況下,你可能但願在父組件中引用子節點的 DOM 節點。一般不建議這樣作,由於它會打破組件的封裝,但它偶爾可用於觸發焦點或測量子 DOM 節點的大小或位置。api
若是你使用 16.3 或更高版本的 React, 這種狀況下咱們推薦使用 ref 轉發。數組
Refs轉發瀏覽器
Ref 轉發是一項將 ref 自動地經過組件傳遞到其一子組件的技巧。對於大多數應用中的組件來講,這一般不是必需的。但其對某些組件,尤爲是可重用的組件庫是頗有用的。
Ref 轉發是一個可選特性,其容許某些組件接收 ref
,並將其向下傳遞(換句話說,「轉發」它)給子組件。
在下面的示例中,FancyButton
使用 React.forwardRef
來獲取傳遞給它的 ref
,而後轉發到它渲染的 DOM button
:
const FancyButton = React.forwardRef((props, ref) => ( <button ref={ref} className="FancyButton"> {props.children} </button> )); // 你能夠直接獲取 DOM button 的 ref: const ref = React.createRef(); <FancyButton ref={ref}>Click me!</FancyButton>;
這樣,使用 FancyButton
的組件能夠獲取底層 DOM 節點 button
的 ref ,並在必要時訪問,就像其直接使用 DOM button
同樣。
如下是對上述示例發生狀況的逐步解釋:
React.createRef
建立了一個 React ref 並將其賦值給 ref
變量。ref
爲 JSX 屬性,將其向下傳遞給 <FancyButton ref={ref}>
。ref
給 forwardRef
內函數 (props, ref) => ...
,做爲其第二個參數。ref
參數到 <button ref={ref}>
,將其指定爲 JSX 屬性。ref.current
將指向 <button>
DOM 節點。第二個參數 ref
只在使用 React.forwardRef
定義組件時存在。常規函數和 class 組件不接收 ref
參數,且 props 中也不存在 ref
。
Ref 轉發不只限於 DOM 組件,你也能夠轉發 refs 到 class 組件實例中。
React 也支持另外一種設置 refs 的方式,稱爲「回調 refs」。它能助你更精細地控制什麼時候 refs 被設置和解除。
不一樣於傳遞 createRef()
建立的 ref
屬性,你會傳遞一個函數。這個函數中接受 React 組件實例或 HTML DOM 元素做爲參數,以使它們能在其餘地方被存儲和訪問。
React 將在組件掛載時,會調用 ref
回調函數並傳入 DOM 元素,當卸載時調用它並傳入 null
。在 componentDidMount
或 componentDidUpdate
觸發前,React 會保證 refs 必定是最新的。
若是你以前使用過 React,你可能瞭解過以前的 API 中的 string 類型的 ref 屬性,例如 "textInput"
。你能夠經過 this.refs.textInput
來訪問 DOM 節點。咱們不建議使用它,由於 string 類型的 refs 存在 一些問題。它已過期並可能會在將來的版本被移除。
findDOMNode
是一個訪問底層 DOM 節點的應急方案(escape hatch)。在大多數狀況下,不推薦使用該方法,由於它會破壞組件的抽象結構。嚴格模式下該方法已棄用。
ReactDOM.findDOMNode(component)
若是組件已經被掛載到 DOM 上,此方法會返回瀏覽器中相應的原生 DOM 元素。此方法對於從 DOM 中讀取值頗有用,例如獲取表單字段的值或者執行 DOM 檢測(performing DOM measurements)。
大多數狀況下,你能夠綁定一個 ref 到 DOM 節點上,能夠徹底避免使用 findDOMNode。
當組件渲染的內容爲 null
或 false
時,findDOMNode
也會返回 null
。當組件渲染的是字符串時,findDOMNode
返回的是字符串對應的 DOM 節點。
從 React 16 開始,組件可能會返回有多個子節點的 fragment,在這種狀況下,findDOMNode
會返回第一個非空子節點對應的 DOM 節點。
findDOMNode
只在已掛載的組件上可用(即,已經放置在 DOM 中的組件)。若是你嘗試調用未掛載的組件(例如在一個還未建立的組件上調用 render()
中的 findDOMNode()
)將會引起異常。nullfalsefindDOMNodenullfindDOMNodefindDOMNodefindDOMNoderender()findDOMNode()
findDOMNode
不能用於函數組件。
ReactDOM.unmountComponentAtNode(container)
從 DOM 中卸載組件,會將其事件處理器(event handlers)和 state 一併清除。若是指定容器上沒有對應已掛載的組件,這個函數什麼也不會作。若是組件被移除將會返回 true
,若是沒有組件可被移除將會返回 false
。truefalse