Function components cannot have string refs in React

avatar
Borislav Hadzhiev

Last updated: Apr 6, 2024
2 min

banner

# Function components cannot have string refs in React

The error "Function components cannot have string refs" occurs when we use a string as a ref in a function component.

To solve the error use the useRef() hook to get a mutable ref object that you can use as a ref inside of the component.

function components cannot have string refs

Here is an example of how the error occurs.

App.js
export default function App() { // A string ref has been found within a strict mode tree. // โ›”๏ธ Function components cannot have string refs. // We recommend using useRef() instead. return ( <div> <input type="text" id="message" ref="msg" /> </div> ); }

The issue in the code sample is that we are using a string as a ref.

# Use the useRef hook to solve the error

To solve the error, use the useRef hook to get a mutable ref object instead.

App.js
import {useEffect, useRef} from 'react'; export default function App() { const refContainer = useRef(null); useEffect(() => { // ๐Ÿ‘‡๏ธ This is reference to input element console.log(refContainer.current); refContainer.current.focus(); }, []); return ( <div> <input type="text" id="message" ref={refContainer} /> </div> ); }

use the use ref hook to solve the error

The code for this article is available on GitHub

The useRef() hook can be passed an initial value as an argument. The hook returns a mutable ref object whose .current property is initialized to the passed argument.

Notice that we have to access the current property on the ref object to get access to the input element on which we set the ref prop.

When we pass a ref prop to an element, e.g. <input ref={myRef} />, React sets the .current property of the ref object to the corresponding DOM node.

The useRef hook creates a plain JavaScript object but gives you the same ref object on every render. In other words, it's pretty much a memoized object value with a .current property.

It should be noted that when you change the value of the current property of the ref, no re-renders are caused.

For example, a ref doesn't have to be included in the dependencies array of the useEffect hook because changing its current property doesn't cause a re-render.

App.js
import {useEffect, useRef} from 'react'; export default function App() { const refContainer = useRef(null); const refCounter = useRef(0); useEffect(() => { // ๐Ÿ‘‡๏ธ This is reference to input element console.log(refContainer.current); refContainer.current.focus(); // ๐Ÿ‘‡๏ธ Incrementing ref value does not cause re-render refCounter.current += 1; console.log(refCounter.current); }, []); return ( <div> <input type="text" id="message" ref={refContainer} /> </div> ); }

ref does not have to be included in dependencies array

The code for this article is available on GitHub

The useEffect hook in the example is only run 2 times because useRef doesn't notify us when its content changes.

Changing the object's current property does not cause a re-render.

If you try to access the ref's current property before its corresponding DOM element is rendered, you'd get a null or an undefined value back.

If you use TypeScript, you might get the error useRef "Object is possibly 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.

Copyright ยฉ 2024 Borislav Hadzhiev