So I have typescript react project where I want to observe certain child components being viewed, to achieve this I am using IntersectionObserver and refs. In my parent component I have an introduction component imported from another file and I am trying to pass introRef into the component to be used to reference elements in Introduction
introRef = useRef(null)
...
<Introduction ref={introRef} />
My Introduction component is defined as follows:
import React, { forwardRef, LegacyRef } from "react";
import myInfo from "../myInfo.json";
const Introduction = forwardRef<HTMLElement, React.HTMLProps<HTMLElement>>((ref) => {
return (
<section ref={ref} className="Introduction">
<p className="greeting">Welcome</p>
<p className="intro">{myInfo.introduction}</p>
<div className="picture">
{/* <PixelateToUnpixelate src={myInfo.myPicture} /> */}
</div>
</section>
);
});
export default Introduction;
on the line : <section ref={ref} className="Introduction">
I am getting the error:
Type ‘HTMLProps’ is not assignable to type ‘LegacyRef | undefined’
To combat the issue I have tried changing the declaration of Introduction to the following
const Introduction = forwardRef((ref:LegacyRef<HTMLElement>) => {
return (
<section ref={ref} className="Introduction">
<p className="greeting">Welcome</p>
<p className="intro">{myInfo.introduction}</p>
<div className="picture">
{/* <PixelateToUnpixelate src={myInfo.myPicture} /> */}
</div>
</section>
);
});
The issue here disappeared, but when I try to use the Introduction component in the parent component and pass pass introRef into Introduction I am getting the error:
Type '{ ref: MutableRefObject<null>; }' is not assignable to type 'IntrinsicAttributes & (LegacyRef<HTMLElement> & RefAttributes<unknown>)'.
Property 'current' is missing in type '{ ref: MutableRefObject<null>; }' but required in type 'RefObject<HTMLElement>'
So again I changed my Introduction component code to:
const Introduction = forwardRef((ref:React.MutableRefObject<null>) => {
return (
<section ref={ref} className="Introduction">
<p className="greeting">Welcome</p>
<p className="intro">{myInfo.introduction}</p>
<div className="picture">
{/* <PixelateToUnpixelate src={myInfo.myPicture} /> */}
</div>
</section>
);
});
Now, I am getting this error when I try to pass introRef into Introduction:
Property 'current' is missing in type '{ ref: MutableRefObject<null>; }' but required in type 'MutableRefObject<null>'.
I am out of ideas on how to solve this as from the documentation from React useRef:
current: Initially, it’s set to the initialValue you have passed. You can later set it to something else. If you pass the ref object to React as a ref attribute to a JSX node, React will set its current property.
So I can’t possibly have the current property if I don’t pass the ref object to a ref attribute to a JSX node, in this case Introduction.
I have also tried doing this without wrapping Introduction in forwardRef, similar issues arose.
What am I doing wrong, how do I create a ref and pass it to a child component in typescript React and please provide an explanation, thank you
2
Answers
So, I went back and read the documentation on forwardRefs and in the documentation, it takes two arguments, but in my code I only gave it one. This was the reason that it was not working and throwing the error. the forwardRefs function, takes in props and the ref to be passed down to the children. I came across another post than in the case where no props is needed you can simply use _: unknown as a sort of placeholder.
React 19
Starting in React 19, you can now access
ref
as a prop for function components –React 18
Supply the types to
forwardRef<...>
–demo on TypeScript playground
Using
React.HTMAttributes<...>
will likely be useful to you. This allows you to specify other props your component will receive –demo on TypeScript playground