7

私は、react-bootstrap の ModalTrigger を使用して、(react-bootstrap の Modal に基づいて) フィールドを多用するモーダルを表示しています。つまり、一連の小道具を送信しています。

<ModalTrigger modal={<MyModal field1={value1} field2={value2} (more fields...)/>}>
    Click here to open
</ModalTrigger>

トリガーを作成する親コンポーネントには、props を介して渡されたフィールド/値があり、そのコンポーネントの親コンポーネントには、実際にデータを保持する最上位コンポーネントによって、props としても渡されます。どちらも基本的にはパイプです。これは、動作しないことを除いて、従来の childContext シナリオです。これが私が試したことの単純化されたバージョンです:

var MyModal = React.createClass({
    contextTypes : {foo : React.PropTypes.string},
    render : function() {
        return (
            <Modal {...this.props} title="MyTitle">
                <div className="modal-body">
                    The context is {this.context.foo}
                </div>
            </Modal>
        );
    }
});

var Content = React.createClass({
    childContextTypes : {foo: React.PropTypes.string},
    getChildContext : function() {return {foo : "bar"}},
    render : function() {
        return (
            <ModalTrigger modal={<MyModal/>}>
                <span>Show modal</span>
            </ModalTrigger>
        )
    }
});

モーダルは、実際のコンテキストを表示せずに、「コンテキストは」でポップアップします。

ModalTrigger に送信されたプロップが何らかの方法で既にレンダリング/マウントされているため、これが発生していると思いますが、理由はわかりません。私の理解では、MyModal の所有者はコンテンツ コンポーネントです。つまり、コンテキストは問題ないはずですが、そうではありません。

いくつかの詳細情報: 私はすでにMyModal に渡そうとしましたが、成功しませんでした{...this.props}context={this.context}また、関連する可能性がありますが、ModalTrigger は cloneElement を使用して、モーダルの onRequestHide prop がトリガーの hide 関数を指すようにします。

それで、私はここで何が欠けていますか?:/

4

2 に答える 2

10

React.cloneElementrefprop がオーバーライドされると、要素の所有者が変更されます。これは、前の所有者からコンテキストが渡されないことを意味します。ただし、 の場合はそうではないようですModalTrigger

所有者ベースのアプローチは、React 0.14 では完全には機能しないことに注意してください。これは、コンテキストが所有者から所有者ではなく、親から子に渡されるためです。そのnode prop を DOM の別のブランチにModalTriggerレンダリングします ( を参照)。したがって、コンポーネントはコンポーネントの子でも子孫でもなく、から子コンテキストが渡されません。modalOverlayMixinModalContentContent

問題を解決するために、子にコンテキストを渡すことのみを目的とするコンポーネントをいつでも作成できます。

var PassContext = React.createClass({
  childContextTypes: {
    foo: React.PropTypes.string
  },

  getChildContext: function() {
    return this.props.context;
  },

  render: function() {
    return <MyModal />;
  },
});

使用するには:

<ModalTrigger modal={<PassContext context={this.getChildContext()}/>}>

Matt Smith が示唆したように、react-bootstrap には、 を介してコンテキストを転送するための非常によく似たアプローチが既に含まれていることがわかりましたModalTrigger.withContext。これにより、VDOM ツリー内の位置に関係なくModalTrigger、コンテキストをノード prop に転送するコンポーネント クラスを作成できます。modal

// MyModalTrigger.js
module.exports = ModalTrigger.withContext({
  foo: React.PropTypes.String
});
于 2015-05-21T11:36:44.013 に答える