(useRef) Cannot assign to 'current' because it is read-only property

avatar

Borislav Hadzhiev

Last updated: Apr 17, 2022

banner

Photo from Unsplash

(useRef) Cannot assign to 'current' because it is read-only property #

The error "Cannot assign to 'current' because it is a read-only property" occurs when we initialize a ref with a null value and don't include null in its type. To solve the error, include null in the ref's type, e.g. const ref = useRef<string | null>(null).

react cannot assign to cuirrent because read only

Here is an example of how the error occurs.

App.tsx
import {useEffect, useRef} from 'react'; const App = () => { const ref = useRef<string>(null); useEffect(() => { // ⛔️ Error: Cannot assign to 'current' because it is a read-only property.ts(2540) ref.current = 'hello'; }, []); return ( <div> <h2>hello world</h2> </div> ); }; export default App;

The issue is that when we pass null as an initial value to the useRef hook and don't include null in the type we passed to the hook's generic, we create an immutable ref object.

To solve the error, we have to include null in the type we are passing to the hook's generic.

App.tsx
import {useEffect, useRef} from 'react'; const App = () => { // 👇️ include null in the ref's type const ref = useRef<string | null>(null); useEffect(() => { ref.current = 'hello'; }, []); return ( <div> <h2>hello world</h2> </div> ); }; export default App;

We used a union type to include null in the ref's type, which makes it a mutable ref object.

Now the ref's type in the example is string or null and its current property can be assigned a value of either of the two types.

The same would be the case if your ref points to a DOM element. You'd have to type the hook as const ref = useRef<HTMLElement | null>(null) if you need to change the value of the ref's current property.

Note that you wound't have to include null in the ref's type if you're not directly assigning to its current property.

App.tsx
import {useEffect, useRef} from 'react'; const App = () => { const ref = useRef<HTMLInputElement>(null); useEffect(() => { ref.current?.focus(); }, []); return ( <div> <input ref={ref} type="text" defaultValue="" /> </div> ); }; export default App;

The ref in the example is used to focus the input element. Because there is no assignment to its .current property, it's not necessary to include null in its type.

Conclusion #

The error "Cannot assign to 'current' because it is a read-only property" occurs when we initialize a ref with a null value and don't include null in its type. To solve the error, include null in the ref's type, e.g. const ref = useRef<string | null>(null).

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.