2016-10-11 12 views
0

私はReactクラスをPanelとし、UIのさまざまな種類の特定のパネルのための再利用可能なコンポーネントとして提供したいと考えています。各パネルには共通のタイトルバーと「送信」ボタンがありますが、各種類のパネルの本体は一意です。継承と合成の小道具

これを達成するために継承(サブクラス化)または合成を使用できますが、この場合は最適ですか?

親クラスPanelにレンダリングメソッドがあり、子パネルがrenderBodyメソッドをオーバーライドしているサブクラス化を試しましたが、これはrenderです。それは、各特定のパネルが独自の小道具(「タイトル」など)を必要とするため、分解されているように見えます。そして、修正された小道具がコンポーネントコンストラクタ内のsuperに渡されたときにReactが苦情を言います。あなたのコンポーネントのコンストラクタが渡されたのと同じ小道具を渡すようにしてください。 「タイトル」は一種のパネルに固有なものなので、最終消費者が「タイトル」小道具自体を指定する必要はありません。

class Panel extends React.Component { 

    render() { 
    return (
     <div> 
     <div>{this.props.title}</div> 
     <div>{this.renderBody()}</div> 
     <div><button>Submit</button></div> 
     </div> 
    ) 
    } 

} 

class SomeSubPanel extends Panel { 

    constructor(props) { 
    // React throws the error message at the following line 
    let newProps = Object.assign({}, props, {title: "Some Sub Panel"}) 
    super(newProps) 
    } 

    renderBody() { 
    return (<div>Panel Body Goes Here</div>) 
    } 

} 

組成物を使用すると、各パネルは、特定の体を持っている必要があり、まだ(HTMLで)体はコンポーネント間で渡すことができないので、サブクラス化と同様に整頓であるように思わないであろう。

再利用可能な親コンポーネントに特性を渡すことができる子コンポーネントを持つ「リアクション方法」は何でしょうか?

多くの感謝!

+0

あなたのコードの一部を投稿することができますか?あなたのサブクラスのコンストラクタは、スーパーに小道具を渡す必要があります。なぜそれが記述だけで問題になるのかわかりません。 – kpie

+0

問題はそのエラーメッセージです。サブクラスは「タイトル」を追加して「小道具」を調整したいが、反作用は小道具を修正することを許可しない。私はいくつかのコードを投稿しようとします。 –

+1

特に、ステートレスな反応成分が(すべてのものが等しい)一般的に好ましいと考えられる(いくつかの好ましい定義については)という事実に照らして、組成が一般的に好ましいと思う。 – mrmcgreg

答えて

1

明確な構成を使用してください。一般的に、あなた自身のReactコンポーネントを拡張する必要はないと思います。ここではあなたがそれを達成できる方法は次のとおりです。

class ReusablePanel extends React.Component { 
    render() { 
    return (
     <div> 
     <div>{this.props.title}</div> 
     <button onClick={this.props.onSubmit}>Submit</button> 
     {this.props.children} 
     </div> 
    ) 
    } 
} 

class FootballPanel extends React.Component { 
    handleSubmitButtonClick =() => { 
    // do something 
    } 

    render() { 
    return (
     <ReusablePanel title='Football' onSubmit={this.handleSubmitButtonClick}> 
     <div>{/* Football markup */}</div> 
     </ReusablePanel> 
    ) 
    } 
} 

class ArsenalPanel extends React.Component { 
    handleSubmitButtonClick =() => { 
    // do something 
    } 

    render() { 
    return (
     <ReusablePanel title='Arsenal' onSubmit={this.handleSubmitButtonClick}> 
     <div>{/* Arsenal markup */}</div> 
     </ReusablePanel> 
    ) 
    } 
} 
+1

なぜ「自分のリアクタコンポーネントを拡張してはいけないのですか? –

+0

@MarioTacke私は「決して」知らないのですが...コンポーネントを拡張するのは混乱します。コンポーネントをそのまま使用することで、余分なノイズや継承ツリーがなくても、サブクラス化することによってすべてを達成できます。 – azium

+0

この質問に与えられた両方の答えは正しいが、これは最初であり、質問の与えられたクラスパラダイムに従う。ありがとうございます! –

2

私はこれを行うのリアクト方法は単純だと思う:

他の場所で次に
// using a function for brevity, but could be a class 
let Panel = ({ title, handleSubmit, children }) => 
    <div> 
    <h1>{title}</h1> 
    {children} 
    <button onClick={handleSubmit}>Submit</button> 
    </div> 

<Panel title="Foo" handleSubmit={onSubmit}>{specificChildContent}</Panel>