Using forwardRef with React hooks

By Julia Bell

January 5th, 2021

Graphic demonstrating forwardref hook

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:



Continue Learning