2017-06-09 12 views
0

私は反応成分の巣を持っています(それはモーダルです)。親から祖父母からの小道具を経由して機能を継承する方法

<Modal> // Grandparent 
    <Footer> // Parent 
    <Button label="Click Me" clickAction={ 
    () => { 

     /* So what goes here? */ 

     } 
    }/> //Child 
    </Footer> 
</Modal> 

モーダルはすべての子に近似モーダル関数を渡します。この関数は、フッターのすべての子に再び渡されます。

export default class Footer extends React.Component { 

    constructor(props) { 
    super(props); 

    this.handleClose = this.handleClose.bind(this); 
    } 
    handleClose() { 
    this.props.closeModal(); 
    } 

    render() { 

    const childrenWithProps = React.Children.map(this.props.children, 
     (child) => React.cloneElement(child, { 
     closeModal: this.handleClose 
     }) 
    ); 

    return (
     <footer}> 
     {childrenWithProps} 
     </footer> 
    ); 
    } 
} 

このようなボタンクラスの外観の内部:

constructor(props) { 
    super(props); 

    this.click = this.click.bind(this); 
    } 

    click() { 
    this.props.clickAction(); 
    } 


    render() { 

    return <a 
     href='#' 
     onClick={this.click} 
    > 
     {this.props.label} 
    </a> 
    } 

唯一のそれへのアクセス権を持つことになっていますので、私は何をしたくないことは右のボタンに近い方法を焼くれますそれはモーダルのフッターの子です。

私が解決しようとしていること(最初のコードブロックを参照してください)は/ *に入るものです。 */ エリア。 'this'を使用すると 'undefined'が返されるので、closeModalメソッドに手が届かない。

提案がありますか?

+0

問題は何ですか?すでに解決策を見つけたようです。 – djfdev

+0

私が書いた最初のブロックを見てください/ *だからここに行くの? * /。それが私が解決しようとしていることです。 –

答えて

0

ああ、問題を見つけました。矢印関数には 'this'の束縛がありませんでした。

<Button label="Click Me" clickAction={ 
    // Nope 
    //() => {this.closeModal()} 

    // Yup 
    function(){this.closeModal()} 
}/> 
+0

'clickAction = {this.closeModal}'は動作しますか? – Ezra

+0

ナー、「これは未定義だよ」 –

0

小道具を使用する必要があるコンポーネントにのみ小道具を渡すことが考えられます。つまり、単に明示的支柱として、あなたのボタンにcloseModal関数を渡す:

function Footer (props) { 
    return (
    <footer>{props.children}</footer> 
) 
} 

function Button (props) { 
    return (
    <a href='#' onClick={props.onClick}>{props.label}</a> 
) 
} 

class Modal extends React.Component { 
    constructor (props) { 
    super(props) 
    this.closeModal = this.closeModal.bind(this) 
    } 

    closeModal() { 
    /* implement me */ 
    } 

    render() { 
    return (
     <div> 
     <Footer> 
      <Button label='Click Me' onClick={this.closeModal} /> 
     </Footer> 
     </div> 
    ) 
    } 

この道を、あなたはすなわちどの小道具は「目に見えない」渡される、ボタンの背景を考える必要はありませんあなたが使ったcloneElementテクニックのような親パターンを使ってそれに伝えます。 Footerの子コンポーネントの中には、closeModalへのアクセスが必要ない場合があるので、それらに渡す理由はありません。

+0

私はこれについて考えましたが、私はこのことをモーダルに焼きたいとは思わなかった。モーダル、フッター、ボタンは3つの別々のコンポーネントですが、ネストすることができます。 –

+0

あなたはそうする必要はありません!モーダルは実際には 'open'のために小道具を受け入れるだけでよく、それに基づいて条件付きでレンダリングすることができます。親コンポーネント( 'App')がすべての状態を処理する完全な例を次に示します。https://www.webpackbin.com/bins/-KmE9UQuk0FExtF_Fn-s – djfdev

+0

^開いている場合のみモダルをマウントするように編集しました – djfdev

関連する問題