React中函數式聲明組件

本文從屬於React入門與最佳實踐中的React組件基礎react

前文介紹的組件的定義方式主要是聲明式組件,其與傳統的jQuery中以DOM操做爲核心的命令式組件生成相比具備更大的靈活性與可組合性。而實際上隨着應用複雜度與所須要的組件數目的持續增長,咱們所須要的組件也會被劃分爲不少的類型。從組件組合的角度或者所謂動態組件的角度來看,常見的便是HOC模式,即將某個組件做爲另外一個組件的Props或者子組件從而封裝出高階組件。還有另外一種偏向函數式的模式便是構造出函數式組件,就好像Arrow Function同樣,對於無狀態的簡單組件,使用函數式組件的方式聲明,會使得代碼的可讀性更好,而且減小冗餘代碼的數目。在React自己對於界面的抽象能夠用View = f(props),即純粹的界面的渲染函數能夠近似看作純函數。函數式組件與基於Class聲明的組件相比,其具備如下特性:git

  • 不須要聲明類,能夠避免大量的譬如extends或者constructor這樣的代碼github

  • 不須要顯示聲明this關鍵字,在ES6的類聲明中每每須要將函數的this關鍵字綁定到當前做用域,而由於函數式聲明的特性,咱們不須要再強制綁定:web

onClick={this.sayHi.bind(this)}>Say Hi</a>
onClick={sayHi}>Say Hi</a>
  • 貫徹最佳實踐,在React組件複用與組合中咱們會提到,應當避免在底層的展現性組件中混入對於狀態的管理,而應該將狀態託管於某個高階組件或者其餘的狀態容器中。利用函數式聲明組件能夠完全保證不會在組件中進行狀態操做。編程

  • 易於理解與測試frontend

  • 更佳的性能表現:由於函數式組件中並不須要進行生命週期的管理與狀態管理,所以React並不須要進行某些特定的檢查或者內存分配,從而保證了更好地性能表現。函數式編程

最後,經過下圖的對比,能夠看出函數式組件聲明方法的簡潔性:函數

Usage:使用

這裏咱們定義一個簡單的Text組件:性能

class Text extends React.Component {

  render() {

    return <p>{this.props.children}</p>;

  }

}

React.render(<Text>Hello World</Text>, document.body);

上面定義的Text組件能夠看作典型的Pure Components,或者說是Dummy Components,即好像函數式編程中的純函數同樣,輸出徹底由輸入的Props決定,而且不會產生任何的反作用。這種類型的組件會在咱們的應用中佔據很大的份額,而在React 0.14以後也容許咱們以相似於定義函數的方式來定義這種無狀態組件,以下所示:測試

const Text = (props) =>
  <p>{props.children}</p>;
// ReactDOM is part of the introduction of React 0.14
ReactDOM.render(
  <Text>Hello World</Text>, 
  document.querySelector('#root')
);

這種模式主要是鼓勵在大型項目中儘量地以簡單的寫法來分割本來龐大的組件,而將來React也會面向這種無狀態的組件在譬如避免無心義的檢查或者內存分配領域進行一些專門的優化。這種無狀態函數式組件的寫法也是支持設置默認的Props類型與值的:

const Text = ({ children }) => 
  <p>{children}</p>
Text.propTypes = { children: React.PropTypes.string };
Text.defaultProps = { children: 'Hello World!' };

咱們也能夠利用ES6默認函數參數的方式來設置默認值:

const Text = ({ children = 'Hello World!' }) =>
  <p>{children}</p>

另外,在無狀態的組件函數中,咱們也是能夠訪問Context的:

const Text = (props, context) =>
  <p style={context}>props.children</p>;
Text.contextTypes = {
  fontFamily: React.PropTypes.string
};
class App extends React.Component {
  static childContextTypes = {
    fontFamily: React.PropTypes.string
  }
  getChildContext() {
    return {
      fontFamily: 'Helvetica Neue'
    };
  }
  render() {
    return <Text>Hello World</Text>;
  }
}

相關文章
相關標籤/搜索