Linguine Code

How to use React useRef with TypeScript

Are you getting a crazy amount of errors from TypeScript when you’re using React.useRef typing?

React useRef  incorrect type definition messages.

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:


// <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.

Console logging useRef DOM reference object

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');
}

GitHub Source link