This is one of the subjects that you know that you have used before but can't clearly explain. Here I am writing for my future self and hopefully any audience on how and why to use forwardRef.

Focusing inputs since '92

Say you have an input and you wanted to make that input focus. To do that it's pretty easy in React. Just use a prop duh!

jsx
const ParentComponent = () => {
   const inputRef = React.useRef();
   const focusInput = () => {
      inputRef.current.focus()
   }
   return (
   <>
      <button onClick={focusInput}>Focus</button>
       <input defaultValue="i" ref={inputRef} />
   </>
)}

This is great if you have the input and the component making the action in the same component but sometimes that is not the case.

Focusing inputs from a parent component

Sometimes you want to handle form items from their parent component. This usually happen if your input controls are not native components but rather more complicated.

Let's create a ParentComponent that renders a button and a `FancyInput` component. When I click on the button I want to focus this input.

jsx
const FancyInput = () => {
   return ( 
   <>
      <span>Fancy</span>
      <input />
   </>
)}

So my first instinct for accomplishing this was using props. I would create a ref in the ParentComponent pass that ref to the FancyInput as a prop and handle the clicking in the ParentComonent as follows

jsx
const ParentComponent = () => {
   const inputRef = React.useRef()
   const focusInput = () => {
      inputRef.current.focus()
   }
    return (
     <div>
        <button onClick={focuInput}>Focus Input</button>
         <FancyInput inputRef={inputRef}/>
     </div>
    ) 
}

This will work just fine but it feels counter-intuitive. It would be much neater to treat my fancy input like any other input and send the necessary ref in a ref attribute. This exactly is the function of `forwardRef`.

Using forwardRef Api

The small refactor that should be done to the parent component is replacing the inputRef prop with the ref native prop

jsx
const ParentComponent = () => {
   const inputRef = React.useRef()
   const focusInput = () => {
      inputRef.current.focus()
   }
    return (
     <div>
        <button onClick={focuInput}>Focus Input</button>
         <FancyInput ref={inputRef}/>
     </div>
    ) 
}

As for the FancyInput, we can use the new(ish) syntax

jsx
const FancyInput = React.forwardRef((props, ref) => {
   return ( 
   <>
      <span>Fancy</span>
      <input ref={ref} />
   </>
)})

You will notice that this is quite similar to the example in the documentation and this is true. But hey it's just a reminder.

Never Miss a Codecrumb!