How to Fix useRef React Hook "Cannot Assign to ... Read Only Property" TypeScript Error?

If you encounter the TypeScript error, "Cannot assign to 'current' because it is a read-only property" when using the React useRef hook, it is likely because the result of useRef has the type React.RefObject (which makes the reference object's "current" property readonly). It is defined like so:

interface RefObject<T> {
    readonly current: T | null;
}

To understand why this is the case, you need to know that RefObject is returned by one of TypeScript's three overloads for the React useRef() hook, which are defined as follows:

function useRef<T>(initialValue: T): MutableRefObject<T>;
function useRef<T>(initialValue: T|null): RefObject<T>;
function useRef<T = undefined>(): MutableRefObject<T | undefined>;

Where the MutableRefObject return type is defined as follows:

interface MutableRefObject<T> {
    current: T;
}

If it's not already clear why and when we get the return type as RefObject, it is when:

  1. The initial value of useRef is set to null (e.g. useRef(null)), and;
  2. The current property is initialized to a specific type (e.g. useRef<HTMLDivElement>).

For example:

const elem = useRef<HTMLDivElement>(null);

type Test = typeof elem; // Test = React.RefObject<HTMLDivElement>

As you might have already guessed, you can fix this by simply making the result of useRef directly mutable. This can be done by including | null in the type of the generic argument. For example:

const elem = useRef<HTMLDivElement|null>(null);

type Test = typeof elem; // Test = React.MutableRefObject<HTMLDivElement|null>

Now, as you can see from the example above, the type of the reference object is a mutable object (i.e. React.MutableRefObject) which allows modification of the current property.


This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.