React.createClass 對比 extends React.Component

今天在寫代碼的時候,忽然想到這個問題,因而找了一篇文章,文章地址:https://toddmotto.com/react-create-class-versus-component/
如下是翻譯,若是有不對的地方,歡迎指正。react

大多數狀況下,能夠認爲是實現同一個功能的兩種方法。React提供了React.createClass方法來建立組件類, 併發布了一個語法糖更新,經過擴展React.Component類而不是調用createClass的方法, 更好地使用ES6模塊。api

    1. 1.語法區別
    2. 2.propTypes and getDefaultProps
    3. 3.State區別
    4. 4.「this」的區別
    5. 5.Mixins
    6. 6.建議

這些差別在各個地方都很微妙,有許多值得探討的差別,瞭解這些差別,幫助你作出最適合決策。數組

語法區別

首先,咱們經過查看兩個代碼示例,對它們進行註釋來研究語法差別。瀏覽器

React.createClass
在這裏咱們指定React類的變量Contacts , 運用render函數來完成一個典型的基礎組件定義。併發

import React from 'react';
const Contacts = React.createClass({
  render() {
    return (
      <div></div>
    );
  }
});
export default Contacts;

React.Component
參考上面的代碼,用ES6 的 class 實現一個相同的組件。函數

import React from 'react';
class Contacts extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div></div>
    );
  }
}
export default Contacts;

從JavaScript的角度來看,咱們如今使用的是ES6類,一般這會與Babel之類的一塊兒使用,將ES6編譯爲ES5在瀏覽器中工做。 經過上面的寫法,用到了constructor,須要調用super()將props傳遞給React.Component。
對於React更改,咱們從React.Component擴展獲得一個名爲「Contacts」的類, 而不是直接調用React.createClass,減小了的React模板的使用,更多的用到了JavaScript。 這是一個重要的改變,要注意這個語法變化帶來的進一步變化。this

propTypes and getDefaultProps

讓咱們來看看, 如何使用和聲明default props,以及它們的類型和設置初始狀態的重要變化。spa

React.createClass
在React.createClass中,propTypes屬性是一個Object,咱們能夠在其中聲明每一個prop的類型。 getDefaultProps屬性是一個返回Object來建立初始props的函數翻譯

import React from 'react';
const Contacts = React.createClass({
  propTypes: {
  },
  getDefaultProps() {
    return {
    };
  },
  render() {
    return (
      <div></div>
    );
  }
});
export default Contacts;

 

React.Component
這將propTypes用做實際Contacts類的屬性,而不是做爲createClass定義Object的的屬性。 我認爲建立類屬性是更好的語法,本身定義類屬性,比用react 的 api 更加清晰。
getDefaultProps如今已經變成了名爲defaultProps的Object類屬性,它再也不是「get」函數,它只是一個Object。 我喜歡這種語法,由於它避免了更多的React模板,只是普通的JavaScript。code

import React from 'react';
class Contacts extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div></div>
    );
  }
}
Contacts.propTypes = {
};
Contacts.defaultProps = {
};
export default Contacts;

 

State區別

狀態的變化頗有趣,咱們使用構造函數實現初始狀態更改。
React.createClass
這裏有一個getInitialState函數,它只是返回一個初始狀態的對象。

import React from 'react';
const Contacts = React.createClass({
  getInitialState () {
    return {
    };
  },
  render() {
    return (
      <div></div>
    );
  }
});
export default Contacts;

 

React.conponent
getInitialState函數已經廢棄,咱們將全部狀態聲明爲構造函數中的一個簡單的初始化屬性,這更像JavaScript,更少的「API」驅動。

import React from 'react';
class Contacts extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
    };
  }
  render() {
    return (
      <div></div>
    );
  }
}
export default Contacts;

 

「this」的區別

使用React.createClass會自動綁定this的值到組件上,但使用ES6類時不會自動綁定。

React.createClass
帶有this.handleClick綁定的onClick聲明。 當這個方法被調用時,React會將正確的執行上下文應用於handleClick。

import React from 'react';
const Contacts = React.createClass({
  handleClick() {
    console.log(this); // React Component instance
  },
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }
});
export default Contacts;

 

React.Component
對於ES6類,類的屬性不會自動綁定到React類實例。

import React from 'react';
class Contacts extends React.Component {
  constructor(props) {
    super(props);
  }
  handleClick() {
    console.log(this); // null
  }
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }
}
export default Contacts;

 


有幾種方法能夠綁定正確的上下文,如下是如何綁定內聯:

import React from 'react';
class Contacts extends React.Component {
  constructor(props) {
    super(props);
  }
  handleClick() {
    console.log(this); // React Component instance
  }
  render() {
    return (
      <div onClick={this.handleClick.bind(this)}></div>
    );
  }
}
export default Contacts;

 


或者,能夠在構造函數內部更改this.handleClick的上下文以免內聯重複,用這種方法避免修改JSX,是更好的方法:

import React from 'react';
class Contacts extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    console.log(this); // React Component instance
  }
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }
}
export default Contacts;

 

Mixins

使用ES6中編寫的React組件時,再也不支持React mixins。
React.createClass
使用React.createClass,咱們可使用mixins屬性將mixin添加到組件,該屬性須要一個可用的mixin數組。 而後這些擴展組件類。

import React from 'react';
var SomeMixin = {
  doSomething() {
  }
};
const Contacts = React.createClass({
  mixins: [SomeMixin],
  handleClick() {
    this.doSomething(); // use mixin
  },
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }
});
export default Contacts;

 

React.Component
不支持

 

建議

Facebook確實建議未來完全刪除React.createClass以支持ES6類 。 如今,它們都只是語法不一樣的語義,它們作一樣的事情 - 它們都是類!

相關文章
相關標籤/搜索