React refs explained simply

Getting started

A React “ref” is an object that references a raw DOM (Document Object Model) element. A ref object provides a way for a React component to access the properties and methods of some underlying DOM element.

To create a ref, you can use the React.useRef() hook:

function App(props) {
    const myRef = React.useRef(); // Create a new ref called 'myRef'
    ...
}

We create a new React ref called myRef. This ref object can now be attached to any HTML DOM element. We can do this by passing the ref object in to a DOM element’s “ref” attribute:

function App(props) {
  const myRef = useRef();

  return <input type="text" ref={myRef} />; //  Attach ref to an input DOM element
}

We attach the ref to an input element via the element’s “ref” attribute. So now, whenever we want to access the input element’s properties or invoke one of it’s methods, we can do that by referencing myRef. A ref object will store a reference to the DOM node in it’s current property. For example, I can access the input element itself by using myRef.current:

function App(props) {
  const myRef = useRef(); // 1) Create a new React ref called 'myRef'
  
  useEffect(() => {
   // 3) Access the input element by using it's 'current' property
   console.log(myRef.current); // "<input type="text"></input>"
   
    myRef.current.focus() // Focus the input element
    myRef.current.value = "React refs are cool" // Change the value in the input box
  }, []);

  return <input type="text" ref={myRef} />; // 2) Attach ref to the input DOM element
}

One common use case for refs is for managing focus, selection, or for media playback within a component. For example, you could use a ref to automatically focus the input element when a component is rendered, or to automatically play a video in the component.

Another common use case for refs is for when you’re dealing with modals that you want to show and hide. If we have a parent component, A, and a modal component, B, which is a child of A, you can 1) declare a new ref object in A, 2) pass that ref down to the child/modal component B via props, and 3) attach that ref to that modal’s DOM element. Now the parent component has direct access to show or hide the child modal because it has direct access to the underlying DOM node.

In general, you should be careful to not overuse refs because the more you rely on refs to do DOM updates, the less you’re relying on React’s reactivity system to do it. This means that the more you use refs, the less predictable your code becomes because you’re gradually taking away React’s ability to dictate UI updates .

It’s important to note that refs can be used to store regular values as well, not just DOM elements. For example, we can use a ref to store numbers:

function App(props) {
    const numberRef = React.useRef(10); // New ref called 'numberRef' that stores a number instead of a DOM element
    
    numberRef.current = numberRef.current + 1; // Increment 'numberRef' by 1. Remember to use '.current' to get the underlying value!
    
    return <h1> Value of ref: { numberRef.current } </h1>; 
    //  Value of ref: 11
}

So you can use refs to reference values other than DOM elements and you can also update the value of a ref – keeping in mind to use the .current property on the ref. One final thing to note about refs is that whenever a ref value changes, that will NOT cause React to trigger a re-render.

If this article was helpful, tweet it!