React Hook #3 useRef()

React Hook #3 useRef()

ยท

4 min read

React Hooks are v16.8 specification which allows certain backward compactible functionalities without any use of class based ordering.

Let's see the most anticipated hook for state values and to access the DOM nodes with the same as well the use cases.

useRef and resemblance with useState

Here the useRef resembles that of a useState as the former too preserves the value across the component.

Difference occurs that:

  • useRef preserves the values across the Life time of the component, whereas useState values are preserved for the successive renders.
  • useRef does not trigger re-rendering of component, on the other hand useState triggers a re-render whenever the state value changes.

On top of these feature useRef can be used to access the DOM nodes/elements.

How useRef() works ๐Ÿค”

useRef is more of a referral/pointer concept were the name provided for the hook points to any initial value/element and after the render it gets manipulated to point to any other values/elements.

The thing is that useRef returns an object that got a current property, which we manipulate for accessing values to accessing DOM nodes.

Here we use a useRef hook which got a firm hold besides the state values.

import React, { useRef } from 'react';

const UseRefBasics = () => {
  const refContainer = useRef(null);   //initially points to a null
  const divContainer = useRef(null);  //for accessing the DOM node

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(refContainer.current.value); //returns the input fields value
    console.log(divContainer.current);  //returns the div element
  }
  console.log(refContainer);  //returns an object with current property
  return <>
    <form className='form' onSubmit={handleSubmit}>
      <div>
        <input type="text" ref={refContainer} /> 
{/*each html element has a ref attribute*/}
        <button type='submit'>submit</button>
      </div>
    </form>
    <div ref={divContainer}> Hey hashnode fam ๐Ÿ‘‹</div>
  </>;
};

export default UseRefBasics;

Use Case

Implementing a navbar could be a better use case, let's just create one and explain the prominent areas were useRef stands out.

But that doesn't seem any prominent, useRef can do more as think of creating a hamburger for the navbar with dynamicity for the container to take up desired number of links with just a few lines of code.

import React, { useState, useRef, useEffect } from 'react'
import { FaBars } from 'react-icons/fa'
import { links } from './data'   //custom navbar links

const Navbar = () => {
  const [showLinks, setShowLinks] = useState(false);
  const linksContainerRef = useRef(null);    
  const linksRef = useRef(null);

 /*change the container size dynamically whenever the number of link alter*/
  useEffect(() => {
    const linksHeight = linksRef.current.getBoundingClientRect().height;
    if (showLinks) {
      linksContainerRef.current.style.height = `${linksHeight}px`
    } else {
      linksContainerRef.current.style.height = `0px`
    }
  }, [showLinks])

  return (
    <nav>
        <header>
          <button onClick={() => setShowLinks(!showLinks)}>
             <FaBars />
          </button>
        </header>
        <section ref={linksContainerRef}>
          <ul ref={linksRef}>
            {links.map((link) => {
              const { id, url, text } = link;
              return <li key={id}>
                <a href={url}>{text}</a>
              </li>
            })}
          </ul>
        </section>
    </nav >
  )
}

export default Navbar

Major Takeaway

useRef is a sophisticated useState without successive re-render and ability to access the DOM nodes/elements.

Let's connect ๐Ÿ”—

Catch me here ๐Ÿ‘‡


Hope you all liked the post, share your impressions and queries below ๐Ÿ™Œ

ย