The forwardRef hooks allows React users to pass refs to child components. The ref can be created and referenced with useRef
or createRef
and then passed in a parent component. Using forwardRef instead of useRef is useful when a ref needs to be accessed in a parent component.
Using forwardRef
Refs cannot be passed as props to functional components.
This will fail:
import React, {useRef} from 'react';
//DON'T DO THIS
export function ParentComponent() {
const nodeRef = useRef(null);return (
<ChildComponent ref={nodeRef}
)}
export function ChildComponent(props) {
return (
<div ref={props.nodeRef}>
<p>Don't pass refs like this</p>
</div>
)
}
This will work:
import React, {useRef, forwardRef} from 'react';
//DO THIS
export function ParentComponent() {
const nodeRef = useRef(null); return (
<ChildComponent ref={nodeRef}
)};
export function ChildComponent forwardRef((props, ref) {
return (
<div ref={ref}>
<p>Pass refs like this</p>
</div>
)
});
Note that the child component is wrapped in parentheses and ref is separated from props to use forwardRef.
forwardRef code example
In this example, we will create a ref in a parent component so we can use it to set state, and forward the ref to a child component. This is a common use case for forwardRef.
This is simple code a parent page that has a button to open a modal and two functions: toggleModal
, for opening and closing the modal using buttons, and handleOutsideClick
, so the modal can be closed by clicking outside it.
Parent component
import React, { useRef, useState } from 'react;
import ChildModal from './Child';
export function Parent() {
const [modal, setModal] = useState(false); const modalRef = useRef(null); const toggleModal = () => {
setModal(!modal);
} const handleOutsideClick = (e) => {
if(modalRef.current && !modalRef.current.contains(e.target)) {
setModal(false);
}
} return (
<div className="page" onClick={() => handleOutsideClick()}>
<h3>Page title</h3>
<p>Generic page with a button to open a modal</p>
<button type="button" onClick={() => toggleModal()}>
Open modal
<button/>
{modal &&
<ChildModal ref={modalRef} toggleModal={toggleModal}/>
}
</div>
)
}
Child component
import React, { forwardRef } from 'react;
export function ChildModal forwardRef((props, ref) {
return (
<div className="modal" ref={ref}>
<p>This is an info modal</p>
<button type="button" onClick={() => toggleModal()}>
Close modal
<button/>
</div>
)
});
That's the syntax for forwardRef
with an example. More resources can be found here:
- Reacts forwardRef docs and API reference.
- Understanding forwarding refs in React.
- Video: Ben Awad's forwardRef tutorial and useRef tutorial.