DEV Community

Tano Paul
Tano Paul

Posted on

4

useState vs useRef Hooks

React is a powerful tool that allows developers to create powerful websites and apps by combining the programming language of JavaScript with the power of HTML through the use of a syntax extension called JSX (JavaScript XML). In React, one of the more powerful tools is referred to as a "hook", which is a special function that allows you to "hook" onto or use special React features within functional components.

One of the most used hooks is the useState hook that allows you to store and manipulate data in your React program. Its use is essential if one is to build a website that a user is able to interact with. Something crucial to understand, which isn't necessarily a bad thing, is that useState causes re-renders every time the state is updated. In most cases, this is exactly what you want. However, there may be some cases that a developer doesn't want to re-render the component when updating a variable. This is where useRef comes in.

Getting Started with useRef

Like any other hook, the first thing you do is import it at the top of your component in order to declare it.

import { useRef } from 'react';
Enter fullscreen mode Exit fullscreen mode

When initializing useRef, the hook is called differently in both appearance and functionality than useState, which is stored as an array with a variable and setter function. With useRef, it's stored as an object thats key is always "current". You can then place a reference property on a JSX element to "refer" to that element.

const inputRef = useRef(any value);
console.log(inputRef)
// logged on console:   {current: input}
return (
    <div>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </div>
)
Enter fullscreen mode Exit fullscreen mode

Best Use Cases

Most of the time when working in React you'll want to use the useState hook rather than useRef, but there are some cases where useRef will come in handy.

Say you wanted to scroll an image into view. If a programmer used useState to accomplish this, after clicking a button to focus on another picture, useState will re-render the page to land on the desired image. With useRef, you can reference the element that does not need to re-render in order to reach the desired effect.

const listRef = useRef(null);

  function scrollToIndex(index) {
    const listNode = listRef.current;

    const imgNode = listNode.querySelectorAll('li > img')[index];
    imgNode.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest',
      inline: 'center'
    });
  }

  return (
    <>
      <nav>
        <button onClick={() => scrollToIndex(0)}>
          Tom
        </button>
        <button onClick={() => scrollToIndex(1)}>
          Maru
        </button>
        <button onClick={() => scrollToIndex(2)}>
          Jellylorum
        </button>
      </nav>
      <div>
        <ul ref={listRef}>
          <li>
            <img
              src="https://placekitten.com/g/200/200"
              alt="Tom"
            />
          </li>
          <li>
            <img
              src="https://placekitten.com/g/300/200"
              alt="Maru"
            />
          </li>
          <li>
            <img
              src="https://placekitten.com/g/250/200"
              alt="Jellylorum"
            />
          </li>
        </ul>
      </div>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Another use for useRef would be to apply it to a video element so that the video does not re-render every time you hit the play/pause button.

const [isPlaying, setIsPlaying] = useState(false);
  const ref = useRef(null);

  function handleClick() {
    const nextIsPlaying = !isPlaying;
    setIsPlaying(nextIsPlaying);

    if (nextIsPlaying) {
      ref.current.play();
    } else {
      ref.current.pause();
    }
  }

  return (
    <>
      <button onClick={handleClick}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <video
        width="250"
        ref={ref}
        onPlay={() => setIsPlaying(true)}
        onPause={() => setIsPlaying(false)}
      >
        <source
          src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
          type="video/mp4"
        />
      </video>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Some other use cases would be building a stopwatch or creating a click counter.

In conclusion, you should use useRef in React when you need to perform certain tasks that involve managing mutable references to elements or values within your components without causing re-renders.

REFERENCES:
https://react.dev/reference/react/useRef

Heroku

Amplify your impact where it matters most — building exceptional apps.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (1)

Collapse
 
kenneth_sidibe profile image
Kenneth

Very interesting read !

Playwright CLI Flags Tutorial

5 Playwright CLI Flags That Will Transform Your Testing Workflow

  • 0:56 --last-failed: Zero in on just the tests that failed in your previous run
  • 2:34 --only-changed: Test only the spec files you've modified in git
  • 4:27 --repeat-each: Run tests multiple times to catch flaky behavior before it reaches production
  • 5:15 --forbid-only: Prevent accidental test.only commits from breaking your CI pipeline
  • 5:51 --ui --headed --workers 1: Debug visually with browser windows and sequential test execution

Learn how these powerful command-line options can save you time, strengthen your test suite, and streamline your Playwright testing experience. Click on any timestamp above to jump directly to that section in the tutorial!

Watch Full Video 📹️

👋 Kindness is contagious

If this post resonated with you, feel free to hit ❤️ or leave a quick comment to share your thoughts!

Okay