2017-01-26 35 views
0

React.cloneElement()を使用してコンポーネントのchildrenを拡張する可能性のある制限/危険性をテストしました。私が特定した可能性のある危険の1つは、refkeyのような小道具の上書きの可能性です。React.cloneElementでコンポーネント参照を維持する

しかし、リアクトの0.13 release candidate(2015年バック)あたりとして:

しかし、JSXとcloneWithPropsとは違って、それはまた、引用文献を保存します。これは、あなたがそれを参照して子供を得る場合、あなたはあなたの祖先からそれを誤って盗むことはないということを意味します。新しい要素に同じrefが付けられます。

[...]

注:コールバック-REFを使用しない限り、2人の親が、同じ子への参照を持っていることはまだできませんのでReact.cloneElement(child, { ref: 'newRef' })は、REFを上書きしません。

class ChildComponent extends React.Component{ 
    constructor(props){ 
    super(props); 

    this.onClick = this.onClick.bind(this); 
    this.extendsChildren = this.extendChildren(this); 
    } 

    onClick(e) { 
    e.preventDefault(); 

    try{ 
     alert(this._input.value); 
    }catch(e){ 
     alert('ref broken :('); 
    } 
    } 

    extendChildren(){ 
    return React.Children.map(this.props.children, child => { 
     return React.cloneElement(
     child, 
     { 
      ref: ref => this._input = ref 
     } 
    ); 
    }); 
    } 

    render() { 
    return(
     <div> 
     <button onClick={this.onClick}> 
     ChildComponent ref check 
     </button> 
     {this.extendChildren()} 
    </div> 
    ); 
    } 
} 


class AncestorComponent extends React.Component{ 
    constructor(props){ 
    super(props); 

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

    onClick(e) { 
    e.preventDefault(); 

    try{ 
     alert(this._input.value); 
    }catch(e){ 
     alert('ref broken :('); 
    } 

    } 

    render() { 
    return (
    <div> 
     <p> 
      The expected behaviour is that I should be able to click on both Application and ChildComponent check buttons and have a reference to the input (poping an alert with the input's value). 
     </p> 
     <button onClick={this.onClick}> 
     Ancestor ref check 
     </button> 
     <ChildComponent> 
     <input ref={ref => this._input = ref} defaultValue="Hello World"/> 
     </ChildComponent> 
    </div> 
    ); 
    } 
} 

しかし、私のChildComponent内部cloningElementsは、入力フィールドからAncestorComponentのref小道具を上書き:私はクローンの子コンポーネントは、以下の2つのレベルでのレフリーの有効性をテストするには、押し通さsmall React applicationを書かれている

ここで私はrefの小道具が保存され、新しいrefの部分がReact.cloneElementの一部として定義されていると思います。

CodePenを実行することでこれをテストできます。

私が間違っていることはありますか?それ以来、この機能は削除されていますか?

答えて

0

Dan Abramovのresponseによると、参照を上書きすることは、コールバックを使用しても参照を上書きすることになります。現在の参照をコールバック宣言の一部として呼び出す必要があります:

return React.Children.map(this.props.children, child => 
    React.cloneElement(child, { 
    ref(node) { 
     // Keep your own reference 
     this._input = node; 
     // Call the original ref, if any 
     const {ref} = child; 
     if (typeof ref === 'function') { 
     ref(node); 
     } 
    } 
) 
); 
関連する問題