0

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>
)

0

2 Answers 2

0

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Similar with the other answer, I'm now getting this error Argument of type 'DOMRect' is not assignable to parameter of type 'SetStateAction<number>'.
@EricNguyen what value do you actually want to save? The height as a number? The height as a string? The entire DOM rec object? It’s not clear what you want to save in state and as what type.
0

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 in componentDidUpdate() 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(new DOMRect());

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.

5 Comments

I tried this but now getting this error: Argument of type 'DOMRect' is not assignable to parameter of type 'SetStateAction<number>'
@EricNguyen sure it would be setDivSize(divRef.current.getBoundingClientRect().height);. I didn't focus on that aspect as the error was surrounding the typing of the ref.
Ah, I was trying to avoid setting a specific value to a variable, but wanted to save the entire DOMRect to a variable.
@EricNguyen I’m not at a computer to test it right now, but you might try using the following as the initial argument to useState instead of 0: new DOMRect(0, 0, 0, 0)
@EricNguyen I updated my answer with the new initial state value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.