2016-07-02 7 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から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} /> 
    ); 
    } 
} 

あなたが安全にthisの間違ったコンテキストで終わる心配する必要はコールバックとしてコンポーネントメソッドを渡すことができなかったように、自動バインド

createClass構文は、いくつかの便利な自動バインディングを提供します。

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

onClickハンドラは、試してみて、トリガされたイベントとして設定thisthis.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方法はbar性質を持っていない場合にthisセットで終わります。

これを回避するには、コンストラクタ内のメソッドを明示的にバインドするか、矢印関数内からメソッドを呼び出す必要があります。

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に詳述されている特異的に反応するための相違のカップルは、ですが、あなたがすることができるしている場合は、個人的に、私は新しいクラス構文を使用します。

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> 
); 

この1つは非常に簡潔であり、あなたのコンポーネントがステートレスであることを強調している:

3

まず、あなたが言及していない別のオプションもあります。

第2に、クラス構文は特にmixinの使用を許可していません。これは機能でありバグではなく、実際にはミックスインから離れるべきだと言う人もいます。

Dan Abramov makes an argument mixinsはよく構成されず、代わりに高次コンポーネントを提案します。 "Higher order component"は、Reactコンポーネントクラスを取り、いくつかの動作が追加された別のクラスを返す関数の派手な用語です。高次のコンポーネントは「デコレータ」と見ることができます。あなたはそれらをコンポーネントに順番に適用し、お互いを知る必要もなく、それぞれ独自のことを実行します。

これは、古い構文を残して、クラスを使って前進するのがよい理由のようです。

+0

'this.createMarkup'を使用するため、この卸売りを使うことはできません。メソッドをインスタンスから離して、どこかの関数として明示的に定義する必要があります。 –

+0

@DanPrinceおっと、私はそれを逃しました。ありがとう!修正された – Kos

関連する問題