Accepted answer

The idea to always use the same prop for the ref can be achieved by proxying class export with a helper.

class ElemComponent extends Component {
  render() {
    return (
      <div ref={this.props.innerRef}>
        Div has a ref

export default React.forwardRef((props, ref) => <ElemComponent 
  innerRef={ref} {...props}

So basically, we are forced to have a different prop to forward ref, but it can be done under the hub. It's important that the public use it as a normal ref.


Incase you need to reuse this in many difference components, you can export this ability to something like withForwardingRef

const withForwardingRef = <Props extends {[_: string]: any}>(BaseComponent: React.ReactType<Props>) =>
    React.forwardRef((props, ref) => <BaseComponent {...props} forwardedRef={ref} />);

export default withForwardingRef;


const Comp = ({forwardedRef}) => (
 <input ref={forwardedRef} />
const EnhanceComponent = withForwardingRef<Props>(Comp);  // Now Comp has a prop called forwardedRef


This can be accomplished with a higher-order component, if you like:

import React, { forwardRef } from 'react'

const withForwardedRef = Comp => {
  const handle = (props, ref) =>
    <Comp {...props} forwardedRef={ref} />

  const name = Comp.displayName ||
  handle.displayName = `withForwardedRef(${name})`

  return forwardRef(handle)

export default withForwardedRef

And then in your component file:

class Boop extends React.Component {
  render() {
    const { forwardedRef } = this.props

    return (
      <div ref={forwardedRef} />

export default withForwardedRef(Boop)

I did the work upfront with tests & published a package for this, react-with-forwarded-ref:


Basically, this is just a HOC function. If you wanted to use it with class, you can do this by yourself and use regular props.

class TextInput extends React.Component {
    render() {
        <input ref={this.props.forwardRef} />

const ref = React.createRef();
<TextInput forwardRef={ref} />

This pattern is used for example in styled-components and it's called innerRef there.


class BeautifulInput extends React.Component {
  const { innerRef, ...props } = this.props;
  render() (
    return (
      <div style={{backgroundColor: "blue"}}>
        <input ref={innerRef} {...props} />

const BeautifulInputForwardingRef = React.forwardRef((props, ref) => (
  <BeautifulInput {...props} innerRef={ref}/>

const App = () => (
  <BeautifulInputForwardingRef ref={ref => ref && ref.focus()} />

You need to use a different prop name to forward the ref to a class. innerRef is commonly used in many libraries.

Related Query

More Query from same tag