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
ref
to 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: