react: [Basic] useRef in useEffect Object is possibly undefined
What cheatsheet is this about? (if applicable)
How to use typescript and useRef
What’s your issue or idea?
import React, { useEffect, useRef } from 'react'
export default function() {
const myRef = useRef()
useEffect(() => {
myRef.current.classList.add('something')
// Object is possibly 'undefined'.ts(2532)
})
return (
<div ref={myRef}></div>
)
}
The following “works” / “typescript doesn’t complain”… but is that the proper way?
import React, { useEffect, useRef } from 'react'
export default function() {
const myRef = useRef(null)
useEffect(() => {
const node = myRef.current as any
node.classList.add('something')
})
return (
<div ref={myRef}></div>
)
}
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 13
- Comments: 17
Typescript seems to like this one
why not use like this “
useRef<any>()” it works fine btwthink we have addressed this well here https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/hooks/#useref
useRefis a generic so you can pass any type you want into it so that it can internally know what.currentis supposed to be. Since you’re usingnullas the initial value, I think you need to add that to your type you’re declaring as well. SouseRef<HTMLDivElement>(null)should beuseRef<HTMLDivElement | null>(null)so typescript knows yourmyRef.currentproperty can beHTMLDivElementornull.You don’t always have to declare the type your ref will be if you know the type won’t change. For example, if you do something like
typescript will infer it as a boolean:
@hellatan there are overloads for
useRefsuch that if you use a type paramTvsT | nullthe resultant object is different:With the first, the
currentproperty of the object is read-only to you, the consumer. It’s meant to be passed into React as the pointer is maintained by React. In practice, you can still mutate thecurrentproperty of something you pass into React but it’s not recommended as React is supposed to be the owner.If you’re using a ref object to pass into a
refprop for an element, you need to use the| nulloverload, otherwise it will complain to you. The third form is for cases where you maintain the pointer yourself (instead of React).Good to know, it makes sense now. I was looking for readonly (but didn’t know it exists) so your first example
useRef<HTMLDivElement>(null)is exactly what I want.The 3rd example errors for me
Error
code snippet (top component no conditional render)
Maybe because I use CRA, which is a little behind @types/react current 6.9.19, latest 16.9.21
@ferdaber so do you mean when you don’t pass in
T | null, typescript will complain if you try to domyRef.current = 'some new ref'?