useRef hook in React

useRef hook in React

Β·

4 min read

πŸ“‘ Prerequisites

  • Basics of react hooks
  • Basics of JavaScript

πŸ€” What is useRef?

useRef is the react hook that let you store the reference value which will not change due to component re-render.

The syntax of useRef is:

const ref = useRef(initialValue);

ref is the reference object you want to use which has single property i.e current which is initialized to the initialValue you provided.

  • To use the value in the reference you can use ref.current

  • And to update the value you can use ref.current = newValue

There are 2 things that need to keep in mind:

  • The reference value is persisted which means it stays the same between the re-renders.
  • Updating the value of the reference does not cause the component to re-render.

πŸ™„ How useRef is different from useState?

As we know that when we change the state value with the setter function the component will re-render. And as we have seen earlier that updating the reference value of useRef does not cause rerender of the component.

Let's see that in action:

import {useRef} from 'react';

function LogButtonClicks(){
  const count = useRef(0);
  const clickHandler = () => {
    count.current = count.current + 1;
    console.log(`Button clicked ${count.current} times`);
  };
  return <button onClick={clickHandler}>Click me</button>;
}

The component LogButtonClicks will count the number of times the button is clicked and it logs to the console.

Try Demo

But if you try to show this count.current value on view it will not change as the component is not re-render when we change the value of reference.

import { useRef } from "react";

export default function App() {
  const count = useRef(0);
  const clickHandler = () => {
    count.current = count.current + 1;
    console.log(`Button clicked ${count.current} times`);
  };
  return (
    <div className="App">
      <p>Current count: {count.current}</p>
      <button onClick={clickHandler}>Click me</button>
    </div>
  );
}

Try demo

But if you do the same thing using the useState hook, it will re-render the component on every change in the count.

import { useState } from "react";

export default function App() {
  const [count, setCount] = useState(0);
  const clickHandler = () => {
    const newCount = count + 1;
    setCount(newCount);
    console.log(`Button clicked ${count} times`);
  };
  return (
    <div className="App">
      <p>Current count: {count}</p>
      <button onClick={clickHandler}>Click me</button>
    </div>
  );
}

Try demo

πŸ›  Use case of useRef: Implement timer

Let's build the timer using useRef and useState in conjunction.

import { useRef, useState } from "react";

export default function App() {
  const [count, setCount] = useState(0);
  const timerId = useRef(null);

  const startTimer = () => {
    timerId.current = setInterval(() => {
      setCount((prevCount) => prevCount + 1);
    }, 100);
  };

  const stopTimer = () => {
    clearInterval(timerId.current);
  };

  return (
    <div className="App">
      <p>Timer: {count}</p>
      <button onClick={startTimer}>Start</button>
      <button onClick={stopTimer}>Stop</button>
    </div>
  );
}

Try demo

We will store the timerId in the useRef hook. So, the value will be consistent throughout the re-render of the component.

And to show the value of the timer on the view we will use the useState hook as we have to re-render the component to show the change value in the timer.

🀯 Accessing the DOM elements

We can use the useRef hook to access the DOM element as well. These can be done like:

  • We will create the reference const elementRef = useRef(null)
  • We will use the ref attribute to assign our created reference to element <div ref={elementRef}>This is the element</div>
  • After mounting the component elementRef.current will points to the DOM element.
import { useEffect, useRef } from "react";

export default function App() {
  const elementRef = useRef(null);

  useEffect(() => {
    console.log(elementRef.current); //logs <div>This is the element</div>
  }, []);

  return (
    <div className="App">
      <div ref={elementRef}>This is the element</div>
    </div>
  );
}

Try demo

βš’ Use case of useRef: focus on input element

Suppose we have the use-case like to focus on the input element as soon as the user lands on the page. we can use useRef here.

For this, we will create const inputRef = useRef(null) reference and assign that reference to the input element using ref attribute. And in the end, when the component is mounted we will focus the input element using element.focus()

import { useEffect, useRef } from "react";

export default function App() {
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focus();
  }, []);

  return (
    <div className="App">
      <input ref={inputRef} type="text" />
    </div>
  );
}

Try demo

  • We have created the reference using const inputRef = useRef(null)
  • We have used ref to assign our reference value to the DOM element <input ref={inputRef} type="text" />
  • We have accessed the DOM node using inputRef.current.focus()

πŸ€“ References

That's it!!!🀩 I hope you got a little clarity about the useRef hook now.

Thanks for readingπŸ€— thank you.gif

Β