Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I am trying to use
useRef
with TypeScript but am having some trouble.
With my
RefObject
(I assume) I need to access
current
. (ie
node.current
)
I have tried the following
const node: RefObject<HTMLElement> = useRef(null);
const node = useRef<HTMLElement | null>(null);
but when I go to set the
ref
I am always told that X
is not assignable to type 'LegacyRef<HTMLDivElement> | undefined'.
return <div ref={ node }>{ children }</div>
Edit: this should not be restricted to any one type of element so not just
HTMLDivElement | HTMLFormElement | HTMLInputElement
Edit: This should work as an example
import React, { useRef, RefObject } from 'react';
function Test()
// const node = useRef(null);
// const node: RefObject<HTMLElement> = useRef(null);
const node = useRef<HTMLElement | null>(null);
node.current &&
node.current.contains()
){ console.log("current accessed")}
return <div ref={ node }></div>
None of the above worked for me, but turns out the solution was quite simple...
All I was doing wrong was not explicitly including "null" as the parameter in the useRef initialization (it expects null, not undefined).
Also you CANNOT use "HTMLElement" as your ref type, you have to be more specific, so for me it was "HTMLDivElement" for example).
So working code for me was something like this:
const ref = useRef<HTMLDivElement>(null);
return <div ref={ref}> Some Content... </div>
–
I made an update. Use HTMLDivElement
as generic parameter instead of HTMLElement | null
. Also, contains
expects an argument.
UPDATE
useRef
expects generic argument of DOM element type. You don't need to use | null
because RefObject
already knows that current
might be null.
See next type:
interface RefObject<T> {
readonly current: T | null
TS & React are smart enough to figure out that your ref might be null
–
–
–
–
I came here looking for help with an iframe ref. Perhaps this solution will help someone else that's looking for the same thing. I replaced HTMLDivElement
with HTMLIFrameElement
so:
const node = useRef<HTMLIFrameElement>(null);
After looking at all answers here I am not sure that any of them answer/explain the problem fully. In this case problem is two fold:
we need to use a different HTML interface object -> HTMLDivElement
we need to pass a default value to the reference initialization
React useRef function actually has 3 different signatures (in React 16.8):
If the passed default value is the same type as the generic type
function useRef\<T>(initialValue: T): MutableRefObject<T>;
If we pass a default value of the same type as the generic type OR null (as spotted by many responses here)
function useRef\<T>(initialValue: T|null): RefObject<T>;
If we pass no default values AND/OR we pass no generic type
function useRef\<T = undefined>(): MutableRefObject<T | undefined>;
The real issue comes down to incompatibility of MutableRefObject and LegacyRef. I am guessing React team did changes to the data types of references and therefor we have multiple signatures and types of references based on what we pass.
It would be nice to get a nicer error message from react eslint at least as the generic TS error message we get isn't enough to immediately spot what's wrong.
Tl;dr: passing null as the default value in useRef object will give us back the reference object that both satisfies MutableRefObject and LegacyRef (probably)
The reason why you're getting this error in typescript is because you need to type the ref.current and not just the ref
example:
const ref = React.useRef<HTMLDivElement>(null);
Component(props: {ref?: {current: HTMLDivElement}})
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.