Sometimes we need access to 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.
Thanks for reading! :)
Top comments (0)