<p dir="auto"><strong>Do you want to request a <em>feature</em> or report a <em>bug</em>?</strong> Feature</p>
<p dir="auto"><strong>What is the current behavior?</strong></p>
<p dir="auto">The <code class="notranslate">ref</code> attribute passed to a DOM node can be either a callback or a <code class="notranslate">RefObject</code>, but not both. Sometimes, that's exactly what's required: for example, a library like <a href="https://popmotion.io/pose/api/posed/#posed-usage-create-a-posed-component-existing-components" rel="nofollow">react-pose</a> demands ref forwarding to work with a React Component, but you'd also like to retain a reference to the <em>same</em> parent DOM node within that component itself for a different reason. It's often not possible to nest DOM nodes to achieve a similar thing using two different ref attributes as that breaks layout.</p>
<p dir="auto">Here's a link to a naive attempt to achieve this: <a href="https://codesandbox.io/s/4jyw3q3v57" rel="nofollow">https://codesandbox.io/s/4jyw3q3v57</a></p>
<p dir="auto">I'm not surprised this doesn't work as there's no reason for the parent ref callback to fire, but I don't know how else to go about it.</p>
<p dir="auto"><strong>What is the expected behavior?</strong></p>
<p dir="auto">The callback provides the component with its own reference to the parent DOM node, whilst also providing it to the parent component via the passed <code class="notranslate">RefObject</code>.</p>
<p dir="auto">Before React 16.3 we were able to proxy the same element ref to multiple listeners, for example, to grab hold of the element for internal purposes and also expose it publicly, like so:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class MyComponent extends Component {
  attachRef = el =&gt; {
    this.buttonEl = el;
    this.props.buttonRef(el);
  }

  // Do something with `this.buttonEl`

  render () {
    return &lt;button ref={this.attachRef}&gt;Button&lt;/button&gt;;
  }
}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">MyComponent</span> <span class="pl-k">extends</span> <span class="pl-v">Component</span> <span class="pl-kos">{</span>
  <span class="pl-c1">attachRef</span> <span class="pl-c1">=</span> <span class="pl-s1">el</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">buttonEl</span> <span class="pl-c1">=</span> <span class="pl-s1">el</span><span class="pl-kos">;</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">props</span><span class="pl-kos">.</span><span class="pl-en">buttonRef</span><span class="pl-kos">(</span><span class="pl-s1">el</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  <span class="pl-c">// Do something with `this.buttonEl`</span>

  <span class="pl-en">render</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">return</span> <span class="pl-c1">&lt;</span><span class="pl-ent">button</span> <span class="pl-c1">ref</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">attachRef</span><span class="pl-kos">}</span><span class="pl-c1">&gt;</span>Button<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">button</span><span class="pl-c1">&gt;</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">After React 16.3 this is more complicated as the ref prop can be a function or an object:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class MyComponent extends Component {
  buttonRef = React.createRef();

  attachRef = el =&gt; {
    this.buttonRef.current = el;
    
    if (typeof this.props.inputRef === 'function') {
      this.props.inputRef(el);
    } else {
      this.props.inputRef.current = el;
    }
  }

  // Do something with `this.buttonRef.current`

  render () {
    return &lt;button ref={this.attachRef}&gt;Button&lt;/button&gt;;
  }
}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">MyComponent</span> <span class="pl-k">extends</span> <span class="pl-v">Component</span> <span class="pl-kos">{</span>
  <span class="pl-c1">buttonRef</span> <span class="pl-c1">=</span> <span class="pl-v">React</span><span class="pl-kos">.</span><span class="pl-en">createRef</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

  <span class="pl-c1">attachRef</span> <span class="pl-c1">=</span> <span class="pl-s1">el</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">buttonRef</span><span class="pl-kos">.</span><span class="pl-c1">current</span> <span class="pl-c1">=</span> <span class="pl-s1">el</span><span class="pl-kos">;</span>
    
    <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-k">typeof</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">props</span><span class="pl-kos">.</span><span class="pl-c1">inputRef</span> <span class="pl-c1">===</span> <span class="pl-s">'function'</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
      <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">props</span><span class="pl-kos">.</span><span class="pl-en">inputRef</span><span class="pl-kos">(</span><span class="pl-s1">el</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span> <span class="pl-k">else</span> <span class="pl-kos">{</span>
      <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">props</span><span class="pl-kos">.</span><span class="pl-c1">inputRef</span><span class="pl-kos">.</span><span class="pl-c1">current</span> <span class="pl-c1">=</span> <span class="pl-s1">el</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
  <span class="pl-kos">}</span>

  <span class="pl-c">// Do something with `this.buttonRef.current`</span>

  <span class="pl-en">render</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">return</span> <span class="pl-c1">&lt;</span><span class="pl-ent">button</span> <span class="pl-c1">ref</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">attachRef</span><span class="pl-kos">}</span><span class="pl-c1">&gt;</span>Button<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">button</span><span class="pl-c1">&gt;</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto"><strong>First, is this the right approach?</strong></p>
<p dir="auto">And if so, <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts#L53">Typescript types</a> say:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface RefObject&lt;T&gt; {
  readonly current: T | null;
}"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">RefObject</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-k">readonly</span> <span class="pl-c1">current</span>: <span class="pl-smi">T</span> <span class="pl-c1">|</span> <span class="pl-c1">null</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">Which prevents us from assigning to <code class="notranslate">current</code>. <strong>Shouldn't it not be readonly?</strong></p>