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

avatar

Borislav Hadzhiev

Sun Apr 17 20222 min read

banner

Photo by Tamara Bellis

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

Use the search field on my Home Page to filter through my more than 1,000 articles.