React/Refs and this DOM

Refs 提供了一種方式,容許咱們訪問 DOM 節點或在 render 方法中建立的 React 元素javascript

什麼時候使用Refshtml

  • 管理焦點,文本選擇或媒體播放。
  • 觸發強制動畫。
  • 集成第三方 DOM 庫。

避免使用 refs 來作任何能夠經過聲明式實現來完成的事情。(好比:避免在 Dialog 組件裏暴露 open() 和 close() 方法,最好傳遞 isOpen 屬性。)java

建立 Refs

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} />;
  }
}

訪問 Refs

當 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 Refs 暴露給父組件

在極少數狀況下,你可能但願在父組件中引用子節點的 DOM 節點。一般不建議這樣作,由於它會打破組件的封裝,但它偶爾可用於觸發焦點測量子 DOM 節點的大小或位置api

若是你使用 16.3 或更高版本的 React, 這種狀況下咱們推薦使用 ref 轉發數組

Refs轉發瀏覽器

Ref 轉發是一項將 ref 自動地經過組件傳遞到其一子組件的技巧。對於大多數應用中的組件來講,這一般不是必需的。但其對某些組件,尤爲是可重用的組件庫是頗有用的。

Ref 轉發是一個可選特性,其容許某些組件接收 ref,並將其向下傳遞(換句話說,「轉發」它)給子組件。

轉發 refs 到 DOM 組件

在下面的示例中,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 同樣。

如下是對上述示例發生狀況的逐步解釋:

  1. 咱們經過調用 React.createRef 建立了一個 React ref 並將其賦值給 ref 變量。
  2. 咱們經過指定 ref 爲 JSX 屬性,將其向下傳遞給 <FancyButton ref={ref}>
  3. React 傳遞 ref 給 forwardRef 內函數 (props, ref) => ...,做爲其第二個參數。
  4. 咱們向下轉發該 ref 參數到 <button ref={ref}>,將其指定爲 JSX 屬性。
  5. 當 ref 掛載完成,ref.current 將指向 <button> DOM 節點。

第二個參數 ref 只在使用 React.forwardRef 定義組件時存在。常規函數和 class 組件不接收 ref 參數,且 props 中也不存在 ref

Ref 轉發不只限於 DOM 組件,你也能夠轉發 refs 到 class 組件實例中。

 

回調 Refs

React 也支持另外一種設置 refs 的方式,稱爲「回調 refs」。它能助你更精細地控制什麼時候 refs 被設置和解除

不一樣於傳遞 createRef() 建立的 ref 屬性,你會傳遞一個函數。這個函數中接受 React 組件實例HTML DOM 元素做爲參數,以使它們能在其餘地方被存儲和訪問。

React 將在組件掛載時,會調用 ref 回調函數並傳入 DOM 元素,當卸載時調用它並傳入 null。在 componentDidMount 或 componentDidUpdate 觸發前,React 會保證 refs 必定是最新的。

過期 API:String 類型的 Refs

若是你以前使用過 React,你可能瞭解過以前的 API 中的 string 類型的 ref 屬性,例如 "textInput"。你能夠經過 this.refs.textInput 來訪問 DOM 節點。咱們不建議使用它,由於 string 類型的 refs 存在 一些問題。它已過期並可能會在將來的版本被移除。

findDOMNode

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,若是沒有組件可被移除將會返回 falsetruefalse
相關文章
相關標籤/搜索