How to use React useRef with TypeScript
Are you getting a crazy amount of errors from TypeScript when you’re using React.useRef
typing?
Or maybe the error says, “Object is possibly null.”
In today’s short article, I will go over how to properly define, and use your useRef
hook with TypeScript.
The solution
As the first example, I’m going to create an h1 element tag. And I want to get the element reference with TypeScript.
import React, { useRef, useLayoutEffect } from 'react';
const App = () => {
const h1Ref = useRef<HTMLHeadingElement>(null);
console.log(h1Ref) // { current: null }
useLayoutEffect(() => {
console.log(h1Ref); // { current: <h1_object> }
})
return (
<h1 ref={h1Ref}>App</h1>
)
}
export default App;
Let’s go over it really quickly.
I’ve imported the React useRef
, and useLayoutEffect
tooling.
If you’re not familiar with React useLayoutEffect
, I recommend you go read a previous article to learn more about it, “When to use React useRef and useLayoutEffect vs useEffect.”
I then initiated a useRef
hook and added an open and close (<>
) bracket before the parenthesis.
Inside that bracket I used the HTMLHeadingElement
type definition because I’m attempting to get a header element reference.
Each native HTML element has their own type definition. Here are some other examples:
More useRef examples
// <div> reference type
const divRef = React.useRef<HTMLDivElement>(null);
// <button> reference type
const buttonRef = React.useRef<HTMLButtonElement>(null);
// <br /> reference type
const brRef = React.useRef<HTMLBRElement>(null);
// <a> reference type
const linkRef = React.useRef<HTMLLinkElement>(null);
When you create a invoke a useRef
hook, it’s important to pass null as the default value.
This is important because React.useRef
can only be null, or the element object.
I then put the h1Ref
variable inside the ref
property of my H1
element.
After the first render React.useRef
will return an object with a property key called current
.
“Object is possibly null” error
First of all, make sure to use the useLayoutEffect
hook whenever you’re doing any work with the DOM reference object.
Second, make sure you’re always running conditionals to make sure that the reference object is not null.
if (null !== h1Ref.current) {
h1Ref.current.innerText = 'Hello world!';
}
This is important because what if you have a function that accepts a reference but not a null value.
function changeInnerText(el: HTMLElement, value: string) {
el.innerText = value;
}
changeInnerText(h1Ref.current, 'hello world');
This may throw
TypeError: Object is possibly null
Or
TypeError: Cannot set property 'innerText' of null
So always run your conditionals in TypeScript to make sure the DOM reference value is the right type.
function changeInnerText(el: HTMLElement, value: string) {
el.innerText = value;
}
if (null !== h1Ref.current) {
changeInnerText(h1Ref.current, 'hello world');
}
Oh wow, you’ve made it this far! If you enjoyed this article perhaps like or retweet the thread on Twitter:
I like to tweet about TypeScript and React and post helpful code snippets. Follow me there if you would like some too!