Juhana Jauhiainen

Access DOM element in a child component in React

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