I'm using useRef
to reference a div element and storing getBoundingClientRect()
. Upon using it, I get a TypeScript error of Property 'height' does not exist on type 'string'
. How do I address this error?
const divRef = useRef(null);
const [divSize, setDivSize] = useState("0");
setDivSize(divRef.current.getBoundingClientRect());
console.log(divSize.height); // getting TS error: Property 'height' does not exist on type 'string'.
return (
<Content ref={divRef}>
{content}
</Content>
)
CodePudding user response:
Unconditionally calling a setState
function at the top level of any component is always an error, because it initiates the reconciliation algorithm (infinitely). Here is a note from the React documentation (which needs to be updated for functional components):
You may call
setState()
immediately incomponentDidUpdate()
but note that it must be wrapped in a condition like in the example above, or you’ll cause an infinite loop.↳ https://reactjs.org/docs/react-component.html#componentdidupdate
To fix this, wrap the setState
call in the effect hook:
const divRef = useRef<HTMLDivElement>(null);
const [divSize, setDivSize] = useState(0);
useEffect(() => {
if (!divRef.current) return;
const rect = divRef.current.getBoundingClientRect();
setDivSize(rect);
console.log(rect.height);
});
return (
<Content ref={divRef}>
{content}
</Content>
)
Also, you can't use the ref
prop on a functional component.
CodePudding user response:
You can use a generic type with useRef
to something that has getBoundingClientRect
as a valid method, such as HTMLElement
or HTMLDivElement
:
const divRef = useRef<HTMLDivElement>(null);
That should properly allow to access height
of result of getBoundingClientRect()
.
This is purely a solution for typing. The answer by jsejcksn help explain how to handle falsy/undefined ref in an effective way.