Why is typescript complaining when trying to use ref in react?
Asked Answered
S

3

6

I am using ref to animate elements on scroll.

  const foo = () => {
    if (!ref.current) return;
    const rect = ref.current.getBoundingClientRect();
    setAnimClass(
      rect.top >= 0 && rect.bottom <= window.innerHeight ? styles.animClass : ""
    );
  };

This code worked well in next.js app, but when I am using this in create-react-app type-script template, it is complaining that Object is possibly 'null'.

From if (!ref.current) return; it is clear that program will be returned if ref.current does not exist. But still, TypeScript gives error on the next line ref.current.getBoundingClientRect(), pointing at the ref.

How do I solve this issue without removing the null checking from typescript config?

complete file - https://github.com/mayank1513/react-contact-app/blob/master/src/components/ContactListItem.tsx

This is the complete project repo - https://github.com/mayank1513/react-contact-app

As of now, I have bypassed the issue using "strict": false in tsconfig. But I need to do it in strict mode.

Similar issue in this file as well. And this is not resolved even by setting "strict": false in tsconfig. For now, I am just relying on document.getElementById() -- around line 65

Seaboard answered 22/1, 2021 at 5:56 Comment(2)
Optional chaining might suppress the error ref?.current?.getBoundingClientRect()Appointed
Try to this. ref?.current!.getBoundingClientRect()Touzle
E
5

you can cast ref to any as you get it from react.
const ref = useRef(null) as any;

Edit: I wanted to come back and give a more strongly typed solution, but Sakshi's answer does just that. This is the lazy fix, so follow their solution.

Eulogize answered 23/1, 2021 at 6:12 Comment(0)
B
6

Try this:

const ref = useRef() as RefObject<HTMLDivElement>;

const foo = () => {
    if (!ref.current) return;
    const rect = ref.current.getBoundingClientRect();
    setAnimClass(
      rect.top >= 0 && rect.bottom <= window.innerHeight ? styles.animClass : ""
    );
  };
Brownson answered 23/1, 2021 at 6:34 Comment(6)
What is RefObject here? typescript complaining about RefObjectSeaboard
You also have to add an import statement.Add this import { RefObject } from "react";Brownson
this issue is resolved by I get error when using ref={ref} in jsx. Using useRef() as any works great, but I think this is more appropriate approach if jsx also works wellSeaboard
show me your code where are you using your ref ?Brownson
Link in the question itselfSeaboard
Hi, was a silly mistake. I was using the ref in input type. Solved the issue.Seaboard
E
5

you can cast ref to any as you get it from react.
const ref = useRef(null) as any;

Edit: I wanted to come back and give a more strongly typed solution, but Sakshi's answer does just that. This is the lazy fix, so follow their solution.

Eulogize answered 23/1, 2021 at 6:12 Comment(0)
I
4

This is simple just add type HTMLDivElement to useRef, and the error didn't show up anymore:

const ref = useRef<HTMLDivElement>(null);

Bonus: you should always remove the listener inside useEffect:

useEffect(() => {
  foo();
  window.addEventListener("scroll", foo);
  window.addEventListener("resize", foo);
  return () => {
    window.removeEventListener("scroll", foo);
    window.removeEventListener("resize", foo);
  }
}, []);
Intercourse answered 23/1, 2021 at 7:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.