React Series: useRef Hook
Tags: webdev, javascript, tutorial, react
Published: 2023-04-06 20:57:59

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 _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 ignore 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 on 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.

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.