41

In my component, I have the following code to scroll to the bottom of the page:

const el = useRef(null);

useEffect(() => {
    if (el.current === null) { }
    else
        el!.current!.scrollIntoView({ block: 'end', behavior: 'smooth' });

    if (props.loading != true)
        props.fetchFeedbackTaskPageData(submissionId);

}, [])

This el ref is attached to a div (at the bottom of the page) like this:

<div id={'el'} ref={el}></div>

However, I am receiving the following error:

Property 'scrollIntoView' does not exist on type 'never'. TS2339

When I was not using !, I was receiving this error:

Object is possibly 'null'. TS2531

I checked many posts on this issue but did not see how to handle this in react when using useRef and scrollIntoView. Any ideas?

renakre
  • 8,001
  • 5
  • 46
  • 99

2 Answers2

94

For anyone reading this in 2020 its

const el = useRef<null | HTMLDivElement>(null); 

and no longer:

const el = useRef<null | HTMLElement>(null);
Michel Floyd
  • 18,793
  • 4
  • 24
  • 39
Arsh Sharma
  • 1,129
  • 1
  • 7
  • 10
  • 1
    I'm wondering why we should ``useRef`` instead of directly ``document.findElementById()`` – daCoda Sep 27 '22 at 08:01
  • @daCoda It has to do with the Virtual DOM: https://reactjs.org/docs/faq-internals.html – brogrammer Nov 22 '22 at 22:14
  • Great contribution. How could this be adapted for an array of html elements? eg. ```ts const cardRefs = useRef([]); cardRefs.current = cardsPerPage.map( (card, i) => cardRefs.current[i] ?? createRef() ); ``` – Lauro235 Feb 21 '23 at 22:21
37

You have to tell useRef what types other than null it will be assigned to, e.g. useRef<null | number>(null) or in your case useRef<null | HTMLElement>(null).

The problem is that by assigning null as a default value to the ref, typescript can only guess that the type of the ref will be that of it's initial value (null) - which is why you're getting the errors you mentioned. Generally speaking, refs don't have to be DOM components, so useRef's type definition does not assume that it will be assigned to one.