March 29, 2021

Ref forwarding with React function components and Typescript


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
// because of Typescript inference.

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!" />;
};

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 component for debugging purpose and prevent eslint warning.
ChildComponent.displayName = 'ChildComponent';

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:


About me

Me

Hi, I'm Jonathan Experton.

I help companies start, plan, execute and deliver software development projects on time, on scope and on budget.

Montreal, Canada · GMT -4