2016-07-02 85 views
4

我學習Reactjs,我想寫一個基本組成部分,誰能告訴我,爲什麼這個組件語法:ReactJs組件語法,有什麼區別?

import React, { Component } from 'react'; 
export default class AboutPage extends Component { 
render: function() { 
    const { page } = this.props; 
    return (
     <div className="blog-post"> 
      <h2 className="blog-post-title">{page.title.rendered}</h2> 
      <div dangerouslySetInnerHTML={this.createMarkup(page.content.rendered)} /> 
     </div> 
    ); 
    } 
} 

與當前組件不同?

var HelloMessage = React.createClass({ 
render: function() { 
    return <div>Hello {this.props.name}</div>; 
    } 
}); 

爲什麼使用export default class而不只是var HelloMessage = React.createClass({

+0

「而不僅僅是」---這些是不可互換的。 – zerkms

回答

3

createClass語法是創建React組件的原始方法,但似乎它正逐步被淘汰,轉而支持class語法和無狀態功能組件。

如果您要從createClass a class升級組件,有幾個關鍵區別需要注意。

初始狀態&默認道具

隨着createClass你可以聲明,將返回初始狀態和默認屬性給定組件的方法。

React.createClass({ 
    getInitialState() { 
    return { foo: 'bar' }; 
    }, 
    getDefaultProps() { 
    return { baz: 'qux' }; 
    }, 
    componentDidMount() { 
    console.log(
     this.state, // => { foo: 'bar' } 
     this.props // => { baz: 'qux' } 
    ); 
    } 
}); 

對於類語法都進行了更改。相反,您可以在構造函數中分配初始狀態。

class extends React.Component { 
    constructor() { 
    super(); 
    this.state = { foo: 'bar' }; 
    } 
} 

而你聲明默認道具爲靜態屬性。

class Qux extends React.Component {} 
Qux.defaultProps = { baz: 'qux' }; 

混入

createClass語法支持一個名爲混入的概念,它允許您提供哪些是擴充現有的生命週期方法的其他代碼。

const logOnMount = { 
    componentWillMount() { 
    console.log('Mounted!', new Date()); 
    } 
}; 

React.createClass({ 
    mixins: [logOnMount] 
}); 

使用logOnMount混入每當它被安裝將記錄的時間戳到控制檯的任何組分。

不支持混合使用class語法,但可以使用higher-order components來實現相同的目的。

function logOnMount(Component) { 
    return function(props) { 
    console.log('Mounted!', new Date()); 
    return (
     <Component {...props} /> 
    ); 
    } 
} 

自動綁定

createClass語法提供了一些方便的自動綁定,讓你可以安全地通過組件的方法作爲回調,而不必擔心與錯誤的上下文this結束了。

React.createClass({ 
    bar() { 
    return true; 
    }, 
    foo() { 
    this.bar(); 
    }, 
    render() { 
    return <button onClick={this.foo}>Click</button>; 
    } 
}); 

onClick處理程序會嘗試與this設置爲觸發的事件調用this.foo,但由於this.foo被autobound有正確的情況下,有沒有錯誤。

下面是同樣的例子,但有類。

class extends React.Component { 
    bar() { 
    return true; 
    } 
    foo() { 
    this.bar(); // Error - undefined is not a function 
    } 
    render() { 
    return <button onClick={this.foo}>Click</button>; 
    } 
} 

foo的方法與this組的事件,該事件不具有bar屬性結束。

爲了解決這個問題,您需要顯式綁定構造函數中的方法,或者從箭頭函數內部調用方法。

constructor() { 
    this.foo = this.foo.bind(this); 
} 

// or 

render() { 
    return <button onClick={e => this.foo()}>Click</button>; 
} 
+0

'class extends ...'是ES6對不對?或者這也適用於ES5? – Tikkes

+0

這只是一個匿名的Es6課程。 –

1

class語法是ES2015中的新功能,您可以在MDN上閱讀它。

React.createClass函數存在,因爲ES2015之前的JavaScript沒有類的支持。

對於具體的反應有幾點區別,詳見the react docs,但個人而言,如果您能夠,我會使用新的類語法。

3

首先,這裏還有另一種選擇,你沒有提到的:

export default function AboutPage(props) { 
    const { page } = props; 
    const pageContentMarkup = createMarkup(page.content.rendered); 
    return (
    <div className="blog-post"> 
     <h2 className="blog-post-title">{page.title.rendered}</h2> 
     <div dangerouslySetInnerHTML={pageContentMarkup} /> 
    </div> 
); 

這是一個非常簡潔,強調你的組件是無狀態的。其次,類語法顯然不允許使用mixin。有人說這是一個功能,而不是一個bug,我們實際上應該離開mixin。

Dan Abramov makes an argument mixin不能很好地組成,並提出更高階的組件作爲替代。 「高階組件」對於一個函數來說是一個奇特的術語,它接受一個React組件類並返回另一個有一些行爲添加的類。更高階的組件可以被看作「裝飾者」。你將它們應用到一個組件中,他們每個仍然會自己做事,甚至不需要彼此瞭解。

這看起來是一個很好的理由,讓我們留下舊的語法,並繼續向前發展。

+0

值得一提的是,由於使用'this.createMarkup',你不能僅僅使用批發。您需要將該方法從實例移開,並將其明確定義爲函數的某個地方。 –

+0

@DanPrince哎呀,我錯過了'this'。謝謝!修改 – Kos