DEV Community

loading...
Cover image for Ref forwarding with React function components and Typescript

Ref forwarding with React function components and Typescript

jexperton profile image Jonathan Experton Updated on ・2 min read

While ref forwarding is well explained in the official documentation, it can be confusing to type it correctly with function components.

1. Typing the reference to be forwarded

The reference is created with the createRef function.

Unlike the useRef hook, which creates a MutableRefObject whose .current property might be initialized with an undefined value, createRef returns an immutable RefObject so you don't need to bother with the initial value type being different than the final value type.

const refTitle: React.RefObject<Text> = React.createRef<Text>();
// In real life, you don't need to explicitly type refTitle 
Enter fullscreen mode Exit fullscreen mode

In this example the reference will point to a Text component therefore the Text component is passed to createRef as a type argument to explicitly type the referenced value.

2. Forwarding the reference to the child component

With the ref attribute of the child component:

const ParentComponent: React.FC = () => {
  const refTitle = React.createRef<Text>();
  return (
    <ChildComponent ref={refTitle} title="Hello, World!" />
  );
}
Enter fullscreen mode Exit fullscreen mode

3. Assigning the forwarded ref inside the child component

As said in the documentation:

By default, you may not use the ref attribute on function components because they don’t have instances.

If you want to allow people to take a ref to your function component, you can use forwardRef

Then with the forwardRef function:

interface ChildComponentProps { 
  title: string; 
}

const ChildComponent = React.forwardRef<Text, ChildComponentProps>(
  (
    { title }: ChildComponentProps,
    ref: React.ForwardedRef<Text>,
  ): JSX.Element => {
    return (
      <Text ref={ref}>{title}</Text>
    );
  },
);

// Name the component for debugging purpose and prevent eslint warning.
ChildComponent.displayName = 'ChildComponent';
Enter fullscreen mode Exit fullscreen mode

Now there's an immutable RefObject available in the ParentComponent that points to the Text component inside the ChildComponent.

Concrete example

Here is an example with React Native where you can use ref forwarding to focus the device's screen reader on a text once the whole parent component is ready:

Photo by JC Gellidon on Unsplash

Discussion (0)

pic
Editor guide