March 29, 2021
While ref forwarding is well explained in the official documentation, it can be confusing to type it correctly with function components.
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.
With the ref attribute of the child component:
const ParentComponent: React.FC = () => {const refTitle = React.createRef<Text>();return <ChildComponent ref={refTitle} title="Hello, World!" />;};
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
refto your function component, you can useforwardRef
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.
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: