React useRef hook and its use cases

React useRef hook and its use cases

·

4 min read

Lets start with brief introduction of the hooks, React hooks are special built in functions which let us store data, add interactivity and also help in performing side-effects.

Below are some of the most common hooks used in React for special purposes -

  • useState
  • useEffect
  • useContext
  • useReducer
  • useRef

We are going to learn about useRef hook, and some of its use cases. Lets go.....

useRef

useRef is designed to store the reference of an element, you can store the reference of button, reference of input element, or other elements and can perform the required manipulation on that element.

Target input element using useRef

Suppose, we have one input element and on the click of button we want to change the background color of that input element, we can achieve this by using useRef as it allows us to access DOM elements.

useRef(initialValue) accepts one argument which is the initial value of the ref and returns the reference.

const inputRef = useRef(0)

Now, we need to let React know that we need access to an input DOM element and that can be done by assigning this ref to an input element-

export const InputRef = () => {
  const inputRef = useRef();
  return (
    <div>
      <input ref={inputRef} />
    </div>
  );
};

When we assign ref prop to the JSX element, it means that, we need direct reference of that DOM element and React sets the current property of inputRef to the DOM node. Now, lets create the button and on the click of it we want to change the backgroundColor of input element-

export const InputRef = () => {
  const inputRef = useRef();
  const colorHandler = () => {
    inputRef.current.style.backgroundColor = "red";
  };

  return (
    <div>
      <input ref={inputRef} />
      <button onClick={colorHandler}>Change Color</button>
    </div>
  );
};

We know that useRef() returns a reference and a reference is an object which have the special property called current which gives us access to the whole input element and using that we have changed the background color of the input tag. Try Demo

In the same way, if want to add the focus on an input element on the button click we can directly do that with below code -

const addFocus () => {
   inputRef.current.focus();
}

useRef doesn't trigger a component re-rendering?

Yes, you read it right, updating the reference does not cause re-render. Its value will be persisted even when the component gets re-rendered.

Let's see the below example to demonstrate the above scenario-

import { useRef } from "react";
export const Counter = () => {
  const counterRef = useRef(0);

  const increment = () => {
    counterRef.current++;
    console.log(`Clicked ${counterRef.current} times`);
  };

  console.log(`Render ${counterRef.current}`);
  return <button onClick={increment}>Increment Count</button>;
};

countRef.png

As initial state of the counterRef is zero and on clicking the increment button we are getting the updated value in console, and the other console statement "Render ${counterRef.current}" is executed just once, during the initial render of the component, when its value was zero.

So, from the above example we can confirm that the change in the value of reference of useRef hook doesn't cause component re-render.

Difference between useRef and useState

We use useState where we want the state value to get updated with re-render. When we want to track and store the information without re-render we use useRef.

Lets go back to the previous example, what if we want to the print that countRef value on UI every time it's being incremented, will it be updated on UI? No, why? Because, as we have discussed earlier, updating a reference doesn't cause re-render of the component, so it will show the same initial value(i.e, zero) every time we hit the increment button.

import { useRef } from "react";
export const Counter = () => {
  const counterRef = useRef(0);

  const increment = () => {
    counterRef.current++;
    console.log(`Clicked ${counterRef.current} times`);
  };

  console.log(`Render ${counterRef.current}`);
  return (
    <>
      <div>{`CounterRef value is ${counterRef.current}`}</div>
      <br />
      <button onClick={increment}>Increment Count</button>
    </>
  );
};

We've modified the above example to show the counterRef value in UI and you can see that though it's value in incremented and printed in console but on UI it's not updating.

image.png

Now, as we already know the solution, we can use useState instead of useRef if we want the component to re-render and to view the updated value on UI.

This was the quick intro of useRef hook and how it can be used in React. We have seen accessing the DOM is the main use case, but it doesn’t mean that it’s the only one! useRef can also be very useful to hold a mutable value across different renders of your component.