TypeScript Course
TypeScript
/
Advanced

React: forwardRef & Typing Refs

Definition

Using `React.forwardRef` to pass DOM refs down into custom child components, and properly typing the ref object using Generics.

Explain Like I'm New

Normally, you cannot pass a `ref` prop to a custom React component (like `<MyButton ref={btnRef} />`). React forces you to wrap the component in `forwardRef` to unlock it. However, wrapping it messes up TypeScript's understanding of the component, requiring very specific Generic types to fix.

Real World Example

Creating a reusable `FancyInput` component that needs to allow parent forms to call `.focus()` on the actual HTML input element buried inside it.

Common Use Cases

  • •Reusable UI libraries
  • •Focus management
  • •Integration with D3/Chart.js

Interactive Example

import React, { forwardRef } from 'react';

type InputProps = {
  label: string;
  placeholder?: string;
};

// Note the generic order: <RefType, PropsType>
export const CustomInput = forwardRef<HTMLInputElement, InputProps>(
  (props, ref) => {
    return (
      <div>
        <label>{props.label}</label>
        {/* The ref is successfully forwarded to the real DOM node */}
        <input ref={ref} placeholder={props.placeholder} />
      </div>
    );
  }
);

// Usage in Parent Component:
// function Parent() {
//   const inputRef = useRef<HTMLInputElement>(null);
//   return <CustomInput ref={inputRef} label="Email" />;
// }

Interview Questions

basic

  • What two arguments does a `forwardRef` render function take?

intermediate

  • When typing `React.forwardRef<T, P>`, what does `T` represent and what does `P` represent?

advanced

  • How do you expose custom methods to a parent ref using `useImperativeHandle`?

Flash Cards

Question

What two arguments?

Click to reveal answer
Answer

`props` and `ref`. e.g., `(props, ref) => <input ref={ref} />`

Question

What do T and P represent?

Click to reveal answer
Answer

This is notoriously confusing in React TS. `T` is the type of the DOM element being referenced (e.g., `HTMLInputElement`). `P` is the type of the Props (e.g., `InputProps`). Notice they are backwards compared to normal functions!