title: Maintaining Component Refs Through React.cloneElement
body: <p>I have been testing the possible limitations/dangers of using <code>React.cloneElement()</code> to extend a component's <code>children</code>. One possible danger I've identified is the possible overwriting of props such as <code>ref</code> and <code>key</code>.</p>
  <p>However, as per React's <a href="https://facebook.github.io/react/blog/2015/03/03/react-v0.13-rc2.html" rel="noreferrer">0.13 release candidate</a> (back in 2015):</p>
  <blockquote>
  <p>However, unlike JSX and cloneWithProps, it also preserves refs. This means that if you get a child with a ref on it, you won't accidentally steal it from your ancestor. You will get the same ref attached to your new element.</p>
  <p>[...]</p>
  <p>Note: <code>React.cloneElement(child, { ref: 'newRef' })</code> DOES override the ref so it is still not possible for two parents to have a ref to the same child, unless you use callback-refs.</p>
  </blockquote>
  <p>I have written a <a href="http://codepen.io/pvienneau/pen/PWJjKq?editors=0010" rel="noreferrer">small React application</a> that clones children components pushed through, testing for the validity of refs at two levels:</p>
  <pre><code>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 =&gt; {
        return React.cloneElement(
          child,
          {
            ref: ref =&gt; this._input = ref
          }
        );
      });
    }
    
    render() {
      return(
        &lt;div&gt;
        &lt;button onClick={this.onClick}&gt;
          ChildComponent ref check
        &lt;/button&gt;
        {this.extendChildren()}
      &lt;/div&gt;
      );
    }
  }
  
  
  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 (
      &lt;div&gt;
          &lt;p&gt;
            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).
          &lt;/p&gt;
        &lt;button onClick={this.onClick}&gt;
          Ancestor ref check
        &lt;/button&gt;
        &lt;ChildComponent&gt;
          &lt;input ref={ref =&gt; this._input = ref} defaultValue=&quot;Hello World&quot;/&gt;
        &lt;/ChildComponent&gt;
      &lt;/div&gt;
      );
    }
  }
  </code></pre>
  <p>However, cloningElements inside my ChildComponent overwrites the AncestorComponent's <code>ref</code> prop from the input field, where I would expect that <code>ref</code> prop to be preserved, alongside the new <code>ref</code> I defined as part of the <code>React.cloneElement</code>.</p>
  <p>You can test this by running the <a href="http://codepen.io/pvienneau/pen/PWJjKq?editors=0010" rel="noreferrer">CodePen</a>.</p>
  <p>Is there anything I'm doing wrong, or has this feature been dropped since?</p>