How to use forwardRef in Typescript

2 min read

Sometimes we need to pass a ref to another component as a prop (e.g. to control the focus from another component.). In these situations, we can use forwardRef, because, the ref prop is handled a bit differently than a normal prop. Let's see its usage in TypeScript.

To illustrate this example let's create a simple app with an input and a button. The button will be a separate component and when it is clicked the input widget should be focused using its ref.

Code

Inside App.tsx: we add an input and a button component. The ref is created using useRef hook and we can specify the type of the ref. In this case, it is an HTMLInputElement. The button component will be a separate component and we will pass the ref to it.

// App.tsx
import { ButtonComponent } from './ButtonComponent'
 
import { useRef } from 'react'
 
export default function App() {
  const ref = useRef<HTMLInputElement>(null)
 
  return (
    <div className="App">
      <h2>forwardRef example with TypeScript</h2>
      <p>Click to the button to focus on the input</p>
      <ButtonComponent title="Click here to focus the input" ref={ref} />
      <br />
      <input placeholder="Click the button to focus here" ref={ref} />
    </div>
  )
}

Code for ButtonComponent.tsx: we use forwardRef to pass the ref to the button component. The first argument is the type of the ref (HTMLInputElement) and the second argument is the type of the props (PropsType). In this case, the ref is an HTMLInputElement and the props are title which is a string.

// ButtonComponent.tsx
import { forwardRef, RefObject } from 'react'
 
type PropsType = {
  title?: string
}
 
const ButtonComponent = forwardRef<HTMLInputElement, PropsType>(
  ({ title }, ref) => {
    const onClickHandler = () => {
      const inputRef = ref as RefObject<HTMLInputElement>
      inputRef.current?.focus()
    }
 
    return <button onClick={onClickHandler}>{title}</button>
  }
)
 
export { ButtonComponent }

The reason why we need to cast the ref to RefObject inside onClick() is that there are two different kinds of refs. One is an object with a current property and the another is a ref callback (for advanced use cases). So, we need to cast it to RefObject to access the current property. For more information check this Stackoverflow answer (opens in a new tab).

Demo

View on CodeSandbox (opens in a new tab)

2023 © Bekzod Norkuziev.RSS