鍍金池/ 教程/ HTML/ 瀏覽器中的工作原理
顯示數(shù)據(jù)
組件的引用
Controlled Input 值為 null 的情況
Reconciliation
子 props 的類型
組件的詳細說明和生命周期
傳遞 Props
特殊的非 DOM 屬性
組件 API
PureRenderMixin
雙向綁定輔助工具
瀏覽器中的工作原理
深入 JSX
表單組件
Dangerously Set innerHTML
入門
JSX 中的 If-Else
克隆組件
教程
更多的關(guān)于Refs
JSX 的 false 處理
高級性能
Mounting 后 componentWillReceiveProps 未被觸發(fā)
簡介
測試工具集
JSX 陷阱
工具集成(ToolingIntegration)
公開組件功能
通過 AJAX 加載初始數(shù)據(jù)
事件系統(tǒng)
可復(fù)用組件
this.props.children undefined
不可變數(shù)據(jù)的輔助工具(Immutability Helpers)
動態(tài)交互式用戶界面
組件的 DOM 事件監(jiān)聽
復(fù)合組件
動畫
插件
JSX 展開屬性
行內(nèi)樣式
性能分析工具
類名操作
與其他類庫并行使用 React
鍵控的片段
標簽和屬性支持
組件間的通信
React (虛擬)DOM 術(shù)語
JSX 根節(jié)點的最大數(shù)量
在樣式props中快速制定像素值
頂層 API
深入理解 React
自閉合標簽
為什么使用 React?
getInitialState 里的 Props 是一個反模式
與 DOM 的差異

瀏覽器中的工作原理

React提供了強大的抽象,讓你在大多數(shù)應(yīng)用場景中不再直接操作DOM,但是有時你需要簡單地調(diào)用底層的API,或者借助于第三方庫或已有的代碼。

虛擬DOM

React是很快的,因為它從不直接操作DOM。React在內(nèi)存中維護一個快速響應(yīng)的DOM描述。render()方法返回一個DOM的描述,React能夠利用內(nèi)存中的描述來快速地計算出差異,然后更新瀏覽器中的DOM。

另外,React實現(xiàn)了一個完備的虛擬事件系統(tǒng),盡管各個瀏覽器都有自己的怪異行為,React確保所有事件對象都符合W3C規(guī)范,并且持續(xù)冒泡,用一種高性能的方式跨瀏覽器(and everything bubbles consistently and in a performant way cross-browser)。你甚至可以在IE8中使用一些HTML5的事件!

大多數(shù)時候你應(yīng)該呆在React的“虛擬瀏覽器”世界里面,因為它性能更加好,并且容易思考。但是,有時你簡單地需要調(diào)用底層的API,或許借助于第三方的類似于jQuery插件這種庫。React為你提供了直接使用底層DOM API的途徑。

Refs和getDOMNode()

為了和瀏覽器交互,你將需要對DOM節(jié)點的引用。每一個掛載的React組件有一個getDOMNode()方法,你可以調(diào)用這個方法來獲取對該節(jié)點的引用。

注意:

getDOMNode()僅在掛載的組件上有效(也就是說,組件已經(jīng)被放進了DOM中)。如果你嘗試在一個未被掛載的組件上調(diào)用這個函數(shù)(例如在創(chuàng)建組件的render()函數(shù)中調(diào)用getDOMNode()),將會拋出異常。

為了獲取一個到React組件的引用,你可以使用this來得到當前的React組件,或者你可以使用refs來指向一個你擁有的組件。它們像這樣工作:

var MyComponent = React.createClass({
  handleClick: function() {
    // Explicitly focus the text input using the raw DOM API.
    this.refs.myTextInput.getDOMNode().focus();
  },
  render: function() {
    // The ref attribute adds a reference to the component to
    // this.refs when the component is mounted.
    return (
      <div>
        <input type="text" ref="myTextInput" />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.handleClick}
        />
      </div>
    );
  }
});

React.render(
  <MyComponent />,
  document.getElementById('example')
);

更多關(guān)于 Refs

為了學(xué)習(xí)更多有關(guān)Refs的內(nèi)容,包括如何有效地使用它們,參考我們的更多關(guān)于Refs文檔。

組件生命周期

組件的生命周期包含三個主要部分:

  • 掛載: 組件被插入到DOM中。
  • 更新: 組件被重新渲染,查明DOM是否應(yīng)該刷新。
  • 移除: 組件從DOM中移除。

React提供生命周期方法,你可以在這些方法中放入自己的代碼。我們提供will方法,會在某些行為發(fā)生之前調(diào)用,和did方法,會在某些行為發(fā)生之后調(diào)用。

掛載

  • getInitialState(): object在組件被掛載之前調(diào)用。狀態(tài)化的組件應(yīng)該實現(xiàn)這個方法,返回初始的state數(shù)據(jù)。
  • componentWillMount()在掛載發(fā)生之前立即被調(diào)用。
  • componentDidMount()在掛載結(jié)束之后馬上被調(diào)用。需要DOM節(jié)點的初始化操作應(yīng)該放在這里。

更新

  • componentWillReceiveProps(object nextProps)當一個掛載的組件接收到新的props的時候被調(diào)用。該方法應(yīng)該用于比較this.propsnextProps,然后使用this.setState()來改變state。
  • shouldComponentUpdate(object nextProps, object nextState): boolean當組件做出是否要更新DOM的決定的時候被調(diào)用。實現(xiàn)該函數(shù),優(yōu)化this.propsnextProps,以及this.statenextState的比較,如果不需要React更新DOM,則返回false。
  • componentWillUpdate(object nextProps, object nextState)在更新發(fā)生之前被調(diào)用。你可以在這里調(diào)用this.setState()。
  • componentDidUpdate(object prevProps, object prevState)在更新發(fā)生之后調(diào)用。

移除

  • componentWillUnmount()在組件移除和銷毀之前被調(diào)用。清理工作應(yīng)該放在這里。

掛載的方法(Mounted Methods)

_掛載的_復(fù)合組件也支持如下方法:

  • getDOMNode(): DOMElement可以在任何掛載的組件上面調(diào)用,用于獲取一個指向它的渲染DOM節(jié)點的引用。
  • forceUpdate()當你知道一些很深的組件state已經(jīng)改變了的時候,可以在該組件上面調(diào)用,而不是使用this.setState()。

跨瀏覽器支持和兼容代碼(Browser Support and Polyfills)

在 Facebook,我們支持老版本的瀏覽器,包括 IE8。我們已經(jīng)擁有適當?shù)?polyfills 很長一段時間了,能夠允許我們寫有遠見的 JS。這意味著在我們的代碼庫中沒有黑客,我們?nèi)匀豢梢云诖覀兊拇a“工作”。例如,不用寫 +new Date(),我們可以只寫 Date.now()。由于開源的 React 和我們內(nèi)部使用的是一樣的,所以我們采取了使用超前思維 JS 的這種理念。

除了那種理念,我們也確立了我們的立場,作為一個 JS 庫的作者,不應(yīng)該把 polyfills 作為庫的一部分 shipping。如果每個庫都這么做,很有可能你會多次發(fā)送相同的 polyfill,這可能相當于一部分無用代碼。如果你的產(chǎn)品需要支持老版本的瀏覽器,很有可能你已經(jīng)在使用類似 es5-shim 的東西了。

為了支持老版本瀏覽器所需的 polyfill

來自 es5-shim.js 提供了 React 所需的如下方法:

  • Array.isArray
  • Array.prototype.every
  • Array.prototype.forEach
  • Array.prototype.indexOf
  • Array.prototype.map
  • Date.now
  • Function.prototype.bind
  • Object.keys
  • String.prototype.split
  • String.prototype.trim

es5-sham.js,同樣來自 ,提供了 React 所需的如下方法:

  • Object.create
  • Object.freeze

React 的 unminified 構(gòu)建需要來自 的如下方法:

  • console.*

當使用 IE8 中的 HTML5 元素時,包括 <section>,<article><nav>,<header><footer>,包含 html5shiv 或類似的一個腳本也是必須的。

跨瀏覽器問題

雖然 React 非常擅長抽象瀏覽器的差異,但是一些瀏覽器是有限制的或呈現(xiàn)出怪異的行為,對于這種行為我們不能找到解決方案。

IE8 的 onScroll 事件

在 IE8 中,onScroll 事件并不 buddle,并且 IE8 沒有一個 API 定義處理程序來捕獲一個事件的階段,這意味著 React 沒有辦法監(jiān)聽這些事件。目前在 IE8 中,事件處理程序被忽略了。

更多信息請看 onScroll 在 IE8 中不起作用的 GitHub 問題。