React Series: useRef Hook

React Series: useRef Hook

If you want to update the value of an element in your component or access any DOM elements, then the useRef() hook is your go-to. When updating state using useState, the component re-renders every time the state is accessed but using useRef, you can be guaranteed that would not occur.

Initializing useRef

useRef hook is first initialized onto a variable that will perform the mutation. It accepts only one argument and returns a reference. The reference is then accessed through a mutable ref keyword in the element where the mutation will take place. Let's see how to initialize a useRef.

import React, { useRef } from 'react'

const Test = () => {

    const inputRef = useRef()

  return (
      <div>Test</div>
  )
}

export default Test

In the code above, inputRef is the variable where our ref will be hooked onto in the return JSX.

Important Points to Note About useRef

  1. It takes in only one initialvalue. The value can be of any type and it is ignored after the initial render.

  2. It returns a reference object that we refer to with the ref keyword in our JSX.

  3. The value of the reference is mutable.

  4. Updating a reference doesn't re-render the component.

  5. The value of the reference is persistent even when the component re-renders.

The ref.current Property.

The ref object returned in useRef is mutable and contains one property called the .current. The current property is where all the actions in our ref object take place. It gives you all the access to the DOM properties of the element you are making a reference to. Let's see some of the properties of .current.

  1. The current property is what helps you mutate the value of your reference.

  2. With the ref.current.contains, you can check if the element you are referencing passes a test. It's just like using (variableName).contains in your string variable while working on arrays.

  3. With the ref.current.focus, you can move the focus of the mouse to a particular element. If you have an application where users need to enter their username before logging in, you can set the focus on the username input box as soon as the application loads.

  4. You can change or re-assign the value of your reference or state with the ref.current.value property.

Now let's see another code example where we will perform a small exercise referencing all the points we mentioned.

const Test = () => {

    const inputRef = useRef()

    const refExample = () => {
        const name = inputRef.current
        inputRef.current = 'My name is Michael'
        console.log(inputRef.current);
    }

  return (
      <div>
          <input type='text' ref={inputRef} />
          <button onClick={refExample}>Click me</button>
    </div>
  )
}
// My name is Michael.

In this example, we are using useRef to update the value of our input element. After creating the inputRef reference, we hooked it to the input element in our JSX. Then we created a callback function where we updated the value of our reference and logged it to the console. The callback is what we are returning in the button element.
Please run the code and click on the button and you'd see the output.

Using useRef to Access The DOM Nodes.

This is one of my favorite ways to use useRef. It can help you access some DOM methods and properties. Once you use the .current property on the ref, it gives you access to some properties that make your application robust.

In this example, I will be using the ref object to output an error in my input element. Let's see how that works.

import React, { useRef, useState } from 'react'

const Test = () => {
    const [name, setName] = useState("")
    const errorRef = useRef()

    console.log(name.length);

    const handleBtn = (e) => {
        if (!name) {
            const nameError = errorRef.current
            errorRef.current.textContent = "Please enter a name"
        } else {
            console.log(name);
        }
   }

  return (
      <>
          <div>
              <h3 ref={errorRef}></h3>
              <input type='text' 
                     value={name} 
                     onChange={((e)=> setName(e.target.value))}/>
          </div>
          <button onClick={handleBtn}>Click me</button>
    </>
  )
}

export default Test

In this example, after setting the ref object to errorRef, it was hooked to the h3 in the input element. We then created a handleBtn function that checks if the user entered a value in the input box. If there is no value in the input box and the button was clicked, the errorRef will output "Please enter a name" to prompt the user to enter a value. if there is a name, it returns.

Using useRef to Focus on an Element

This is another beautiful use for useRef. I guess I mentioned it among the important notes. useRef can be used to focus on important elements on your application. The elements could be username or email input boxes, and they can also be important elements on a form. Let's see how to use if for focus.

import React, { useEffect, useRef} from 'react'

const Test = () => {
    const focusRef = useRef()

    useEffect(() => {
        focusRef.current.focus()
    })
  return (
      <>
          <div>
              <input type='text' ref={focusRef}/>
          </div>
    </>
  )
}

export default Test

In this example, our ref which is focusRef was used in a useEffect, so that once the application loads, the focus of the typing cursor will be on the input element. Please try the code out and you'll see for yourself.

Summary

The value referenced in your ref object will be persistent for the full lifecycle of the component.

Like in one of the examples, the ref will give you access to some DOM nodes. In our case, we were able to access textContent.

useRef dos not re-render when the value of the ref is updated.

I hope this tutorial was helpful. Don't forget to ask me questions if you are confused about anything.

Please like and follow me if you think it's worth it.

Have a great day folks.