Access DOM element in a child component in React

Posted on Aug 18, 2020

Sometimes we need access a DOM element which is contained by another React component. If we try to just use ref and pass it to the child component, we get an error.

function ChildComponent(props) {
  return <div ref={props.ref}>Hello there!</div>;
}

export default function App() {
  const childRef = React.useRef();

  return (
    <div className="App">
      <ChildComponent ref={childRef} />
    </div>
  );
}

This is because ref is a reserved prop name so you can’t pass it to a child component. Instead we can use forwardRef when defining the child component.

const ChildComponent = React.forwardRef((props, ref) => {
  return <div ref={ref}>Hello there!</div>;
});

export default function App() {
  const childRef = React.useRef();

  useEffect(() => {
    console.log(childRef);
  }, [childRef]);

  return (
    <div className="App">
      <ChildComponent ref={childRef} />
    </div>
  );
}

This is pretty nice, and if you’re building a component library, probably the best way to allow your users to access DOM elements of the components.

There is also another way to solve the problem. We can just use a prop name which isn’t reserved!

function ChildComponent(props) {
  return <div ref={props.innerRef}>Hello there!</div>;
}

export default function App() {
  const childRef = React.useRef();

  return (
    <div className="App">
      <ChildComponent innerRef={childRef} />
    </div>
  );
}

This works perfectly fine!

If you want to maintain a consistent API or you’re developing a component library you probably should use forwardRef but if you’re developing an app you could also just use another prop name.


https://reactjs.org/docs/forwarding-refs.html