Assigning a type to the useRef Hook in React can be a little confusing at first. Let us understand it with the help of an example. Run the following code inside the "App.js" file on a React TypeScript application.

import { useEffect, useRef } from "react";

function App() {
  const inputRef = useRef();

  useEffect(() => {
    inputRef.current.focus();
  }, []);

  return (
    <div>
      <input ref={inputRef} />
    </div>
  );
}

export default App;
error code

Straight away, you would get two errors. One states some things like "Type 'MutableRefObject' is not assignable to type ........." and a bunch of verbose like shown below:

error 1

Second error stating that the "Object is possibly 'undefined'."

error 2

Lets try and solve these errors one by one.

Solution for Error 1

The error "Type 'MutableRefObject' is not assignable to type ....." is a lengthy one. Basically it's trying to say that "inputRef.current" could be undefined and is not assignable to "HTMLInputElement".

In order to fix this, we need to add a generic to the useRef Hook and pass "HTMLInputElement" as the type like this:

 const inputRef = useRef<HTMLInputElement>();

How did I get the "HTMLInputElement" as the type? Simply hovering over the input element (assuming using VS Code Editor) would give you some data along with its type. For example, hovering over the input element here would give the following:

(property) JSX.IntrinsicElements.input: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
element hover details

From this data, we can analyse that "HTMLInputElement" is the type.

However, adding the type to the useRef didn't solve the error. That is because , right now the useRef is undefined, which is against the defined type of "HTMLInputElement". We can fix this by initializing the useRef with a "null" value and passing "null" as a either "HTMLInputElement" or "null. See the following code.

import { useEffect, useRef } from "react";

function App() {
  const inputRef = useRef<HTMLInputElement | null>(null); //👈 Modified type and initialized with "null"

  useEffect(() => {
    inputRef.current.focus();
  }, []);

  return (
    <div>
      <input ref={inputRef} />
    </div>
  );
}

export default App;
error 1 solution

Now the first error has been solved since now the assigned types are correct.

Solution for Error 2

The error "Object is possibly 'null'." occurs because if the "inputRef.current" is "null" , then the method "focus()" wouldn't exist within its context. We can fix this by conditionally calling the "focus()" method depending on the existence of "inputRef.current". See the following change:

    inputRef.current?.focus();
error 2 solution

Now, we are conditionally calling "focus()" method. So if "inputRef.current" doesn't exist, "focus()" method would not be called and thereby we avoided the error.

Conclusion

The entire fixed code for the above problems is as follows:

import { useEffect, useRef } from "react";

function App() {
  const inputRef = useRef<HTMLInputElement | null>(null);

  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  return (
    <div>
      <input ref={inputRef} />
    </div>
  );
}

export default App;
Full fixed code

When using useRef hook, make sure you have assigned all the possible types that could be assigned to the useRef and also to conditionally call any methods originating from the useRef.