今天在寫代碼的時候,忽然想到這個問題,因而找了一篇文章,文章地址:https://toddmotto.com/react-create-class-versus-component/
如下是翻譯,若是有不對的地方,歡迎指正。react
大多數狀況下,能夠認爲是實現同一個功能的兩種方法。React提供了React.createClass方法來建立組件類, 併發布了一個語法糖更新,經過擴展React.Component類而不是調用createClass的方法, 更好地使用ES6模塊。api
這些差別在各個地方都很微妙,有許多值得探討的差別,瞭解這些差別,幫助你作出最適合決策。數組
首先,咱們經過查看兩個代碼示例,對它們進行註釋來研究語法差別。瀏覽器
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
讓咱們來看看, 如何使用和聲明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;
狀態的變化頗有趣,咱們使用構造函數實現初始狀態更改。
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;
使用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;
使用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類 。 如今,它們都只是語法不一樣的語義,它們作一樣的事情 - 它們都是類!