React Hooks - UseRef
Tags: webdev, react, beginners, programming
Published: 2024-03-07 23:00:00

Hey guys, In our previous article in the React series, we learned about the React Context Api and how to use the useContext hook. In this article, we’ll be talking about the useRef Hook. Let’s dive right in 😉

## **What is `useRef` in React**

The **`useRef`** hook in React allows you to create a mutable object that persists throughout the component's lifecycle without triggering a re-render and it can’t be used in the return body of the component.

You can think of `useRef` just as `useState` but the difference between them is that `useRef` does not trigger a re-render unlike `useState` and the syntax is a bit different from `useState` too.

💡*This definition may seem a bit abstract initially, but as we progress, it will become clearer.*

### **Basic Syntax**

Here is a basic syntax for using **`useRef`**

```jsx
import { useRef } from 'react';

function MyComponent() {
  const myRef = useRef();
}
```

**`myRef`** is an object with a **`current`** property, initially set to **`undefined`**. This property can be assigned to any value, and it will persist across renders without causing a re-render.

Now that we’ve seen the basic syntax of **`useRef`**, let’s explore some of its use cases.

## **Use Cases**

### 1. Accessing and Manipulating the DOM

One of the primary use cases for **`useRef`** is interacting with the DOM. So instead of using the using `document.querySelector` or other DOM queries, you can use `useRef` to directly reference an element within your component.

Let’s see an example 👇🏽

```jsx
import { useRef, useEffect } from 'react';

function MyComponent() {
  const inputRef = useRef(null);

  useEffect(() => {
    // Focus on the input element on mount
    inputRef.current.focus();
  }, []);

  return <input ref={inputRef} />;
}
```

In this example, we are basically focusing the input element when the component mounts. Here is how the code works.

- Start by storing the **`useRef`** in a variable named **`inputRef`** with an initial value of **`null`**.
- Invoke the **`useEffect`** hook, which executes after the component mounts (with an empty dependency array, **`[]`**).
- Within the **`useEffect`**, access the **`inputRef`** and set its current property to the input element (referenced through the **`ref`** attribute in the input tag). Additionally, append the **`focus()`** method to it.

### 2. Persistent Values

**`useRef`** is useful for persisting values across renders without causing re-renders. This is especially handy when dealing with values that don't affect the visual output but need to be retained.

Let’s see an example 👇🏽

```jsx
import { useRef } from 'react';

function Counter() {
  const countRef = useRef(0);

  const increaseCount = () => {
    countRef.current += 1;
    console.log('Current count:', countRef.current);
  };

  return (
    <div>
      <p>Count: {countRef.current}</p>
      <button onClick={increaseCount}>Increase Count</button>
    </div>
  );
}
```

In this example, the count is stored in **`countRef`**, and modifying it doesn't trigger a re-render.

### **3. Refs with Previous Values**

Sometimes, you may need to store the previous value of a state or prop. You can achieve this using the **`useRef`** hook in conjunction with the **`useEffect`** hook:

```jsx
import { useEffect, useRef, useState } from 'react';

function MyComponent() {
  const [name, setName] = useState('');
  const prevValueRef = useRef();

  useEffect(() => {
    prevValueRef.current = name;
  }, [name]);

  return (
    <div>
      <input type="text" onChange={(e) => setName(e.target.value)} />
      <p>
        My name is {name} but it used to be {prevValueRef.current}
      </p>
    </div>
  );
}
```

In the example above, the previous value is stored in **`prevValueRef`** whenever the **`name`** state changes.

### **Best Practices for using the `useRef` Hook**

1. **Use `useRef` for Mutable Values:** If you have values that need to persist across renders but don't trigger re-renders, **`useRef`** is the appropriate choice.
2. **Avoid Direct DOM Manipulation:** While **`useRef`** is handy for accessing and manipulating the DOM, it's generally recommended to use React's state for managing UI-related changes except in extreme cases.
3. **Understand the `current` Property:** Always access and update the value through the **`current`** property of the **`useRef`** object.
4. **Combine with `useEffect` Wisely:** Use **`useEffect`** to perform actions after rendering, and ensure to include any necessary cleanup logic.

## **Conclusion**

Thank you for dedicating your time to go through this article 🎉. Unlike the topics we've covered before, I didn’t cover all the use cases of **`useRef`** here. This implies that you may need to conduct a bit of research on your own. However, the concepts we delved into today are likely to be the ones you'll encounter frequently when working on real projects.

See you next week and have an amazing weekend 😃