鍍金池/ 教程/ HTML/ DOM 操作
React 組件
Redux 的基礎概念
JSX
DOM 操作
在 React 應用中使用 Redux
進化 Flux
Webpack 配置 React 開發(fā)環(huán)境
服務器端渲染
組合組件
表單
屬性擴散
開發(fā)環(huán)境配置
組件生命周期
Data Flow
JSX 與 HTML 的差異
組件間通信
使用 JSX
事件處理
Flux
React 概覽
Mixins
Redux

DOM 操作

大部分情況下你不需要通過查詢 DOM 元素去更新組件的 UI,你只要關注設置組件的狀態(tài)(setState)。但是可能在某些情況下你確實需要直接操作 DOM。

首先我們要了解 ReactDOM.render 組件返回的是什么?

它會返回對組件的引用也就是組件實例(對于無狀態(tài)狀態(tài)組件來說返回 null),注意 JSX 返回的不是組件實例,它只是一個 ReactElement 對象(還記得我們用純 JS 來構建 JSX 的方式嗎),比如這種:

// A ReactElement
const myComponent = <MyComponent />

// render
const myComponentInstance = ReactDOM.render(myComponent, mountNode);
myComponentInstance.doSomething();

findDOMNode()

當組件加載到頁面上之后(mounted),你都可以通過 react-dom 提供的 findDOMNode() 方法拿到組件對應的 DOM 元素。

import { findDOMNode } from 'react-dom';

// Inside Component class
componentDidMound() {
  const el = findDOMNode(this);
}

findDOMNode() 不能用在無狀態(tài)組件上。

Refs

另外一種方式就是通過在要引用的 DOM 元素上面設置一個 ref 屬性指定一個名稱,然后通過 this.refs.name 來訪問對應的 DOM 元素。

比如有一種情況是必須直接操作 DOM 來實現的,你希望一個 <input/> 元素在你清空它的值時 focus,你沒法僅僅靠 state 來實現這個功能。

class App extends Component {
  constructor() {
    return { userInput: '' };
  }

  handleChange(e) {
    this.setState({ userInput: e.target.value });
  }

  clearAndFocusInput() {
    this.setState({ userInput: '' }, () => {
      this.refs.theInput.focus();
    });
  }

  render() {
    return (
      <div>
        <div onClick={this.clearAndFocusInput.bind(this)}>
          Click to Focus and Reset
        </div>
        <input
          ref="theInput"
          value={this.state.userInput}
          onChange={this.handleChange.bind(this)}
        />
      </div>
    );
  }
}

如果 ref 是設置在原生 HTML 元素上,它拿到的就是 DOM 元素,如果設置在自定義組件上,它拿到的就是組件實例,這時候就需要通過 findDOMNode 來拿到組件的 DOM 元素。

因為無狀態(tài)組件沒有實例,所以 ref 不能設置在無狀態(tài)組件上,一般來說這沒什么問題,因為無狀態(tài)組件沒有實例方法,不需要 ref 去拿實例調用相關的方法,但是如果想要拿無狀態(tài)組件的 DOM 元素的時候,就需要用一個狀態(tài)組件封裝一層,然后通過 reffindDOMNode 去獲取。

總結

  • 你可以使用 ref 到的組件定義的任何公共方法,比如 this.refs.myTypeahead.reset()
  • Refs 是訪問到組件內部 DOM 節(jié)點唯一可靠的方法
  • Refs 會自動銷毀對子組件的引用(當子組件刪除時)

注意事項

  • 不要在 render 或者 render 之前訪問 refs
  • 不要濫用 refs,比如只是用它來按照傳統的方式操作界面 UI:找到 DOM -> 更新 DOM
上一篇:表單下一篇:Redux 的基礎概念