diff --git a/documentation/blog/2024-01-18-react-useref.md b/documentation/blog/2024-10-16-react-useref.md
similarity index 68%
rename from documentation/blog/2024-01-18-react-useref.md
rename to documentation/blog/2024-10-16-react-useref.md
index 486aa197e8d8..ad59f116f679 100644
--- a/documentation/blog/2024-01-18-react-useref.md
+++ b/documentation/blog/2024-10-16-react-useref.md
@@ -8,7 +8,7 @@ image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2022-10-26-react-user
hide_table_of_contents: false
---
-**_This article was last updated on January 18, 2024 to add more usecases for React useRef hook and provide a more detailed explanation of the differences between useRef and React ref._**
+**This article was last updated on October 16, 2024 to add more use cases for the React useRef hook, address common misconceptions, explain performance optimizations, and provide a more detailed comparison between useRef and React ref.**
## Introduction
@@ -28,8 +28,10 @@ Steps we'll cover:
- [Differences between the useRef hook and the createRef function](#differences-between-the-useref-hook-and-the-createref-function)
- [Best practices when working with refs](#best-practices-when-working-with-refs)
- [Using the useRef hook in an Application](#using-the-useref-hook-in-an-application)
+- [Common Pitfalls using useRef](#common-pitfalls-using-useref)
- [When to use React useRef hook?](#when-to-use-react-useref-hook)
- [Use-cases of refs in React](#use-cases-of-refs-in-react)
+- [Performance Optimization with useRef](#performance-optimization-with-useref)
## What is useRef hook?
@@ -252,6 +254,89 @@ Now let’s see the output:
+## Common Pitfalls using useRef
+
+A couple of things that I think folks sometimes misunderstand about `useRef`, including myself up until this week. Here are quick clarifications for each with examples:
+
+### Myth 1: `useRef` and `useState` serve the same purpose.
+
+Actually, `useRef` and `useState` work differently. When you update a value with `useState`, the re-rendering of the component is caused. However, if you do that with the help of `useRef`, the value can change and nothing will happen - your component won't re-render. Here is an example:
+
+```jsx
+const MyComponent = () => {
+ const [state, setState] = useState(0);
+ const ref = useRef(0);
+
+ const updateValues = () => {
+ setState(state + 1); // This will trigger a re-render
+ ref.current += 1; // This will NOT cause a re-render
+ };
+
+ console.log("Component rendered");
+
+ return (
+
+
+ State: {state}
+ Reference: {ref.current}
+
+
+
+ );
+};
+```
+
+This example re-renders the component on every button click because of the `setState` call; however, you won't see `console.log` triggered by that because changes of `ref` value don't trigger a re-render.
+
+### Myth 2: Changing a ref will re-render the component.
+
+It's again a misunderstanding. Setting ref value never re-renders the component. Here is a small example that proves this:
+
+```jsx
+import { useRef } from "react";
+
+const MyComponent = () => {
+ const ref = useRef(0);
+
+ const updateRef = () => {
+ ref.current += 1;
+ console.log("Ref updated:", ref.current); // You can see the updated value in the console
+ };
+
+ console.log("Component rendered");
+
+ return (
+
+ Ref value: {ref.current}
+
+
+ );
+};
+```
+
+Even on every button click, though `ref.current` would change, the component doesn't trigger a re-render because `useRef` updates its value without affecting anything regarding the component lifecycle. So the only place that would see the updated value would be in the console.
+
+### Myth 3: `useRef` must be used only for DOM elements.
+
+While it's true that `useRef` is often used to access DOM elements, you can also use it to store any mutable value that persists across renders. In this example, we'll use `useRef` to count how many times a button gets clicked without causing re-renders:
+
+```jsx
+import { useRef } from "react";
+
+const MyComponent = () => {
+ const clickCount = useRef(0);
+
+ const handleClick = () => {
+ clickCount.current += 1;
+
+ console.log("Button clicked", clickCount.current, "times");
+ };
+ return ;
+};
+```
+
+In this case, `clickCount` keeps track of how many times the button was clicked, but doesn’t trigger a re-render every time the value changes. The count is logged in the console.
+
## When to use React useRef hook?
1. **Accessing DOM Elements**: `useRef` is often used to directly access a DOM element in your JSX. This is useful for things like focusing on an input field upon a component mounting.
@@ -295,6 +380,100 @@ const MyComponent = () => {
Because the `FunctionalComponent` component does not have an instance, the ref in the code above will not work. Instead, youcan convert the `FunctionalComponent` into a class component or use `forwardRef`.
+## Performance Optimization with useRef
+
+Here is an example of how we can use `useRef` to optimize the performance of React components by avoiding extra re-renders. See some examples below that show how `useRef` can help in different scenarios:
+
+### Avoiding Re-renders when Storing Mutable Values
+
+If you need to store some value that doesn't need to trigger a re-render when changed, then `useRef` is perfect. For example, if you're storing mutable data like a previous value, using `useState` would cause a re-render every time that value updates, which is often unnecessary:
+
+```jsx
+import { useRef, useState, useEffect } from "react";
+
+const MyComponent = () => {
+ const [count, setCount] = useState(0);
+ const prevCountRef = useRef(0);
+
+ useEffect(() => {
+ prevCountRef.current = count; // Store the previous value without triggering a re-render
+ }, [count]);
+
+ return (
+
+
Current count: {count}
+
Previous count: {prevCountRef.current}
+
+
+ );
+};
+```
+
+In this example, `prevCountRef` stores the previous count without triggering a re-render. This is useful when comparing the current and previous values without affecting the virtual DOM.
+
+### Optimizing Expensive Operations
+
+When there's an expensive operation that doesn’t need to re-run on every render, `useRef` can store those values. For example, if you're dealing with heavy calculations or external API results, you can store the result in a ref to avoid recalculating:
+
+```jsx
+import { useRef, useState, useEffect } from "react";
+
+const ExpensiveCalculationComponent = () => {
+ const [input, setInput] = useState(0);
+ const calculationRef = useRef(null);
+
+ useEffect(() => {
+ if (calculationRef.current === null) {
+ // Do the expensive calculation once and cache the result in ref
+ calculationRef.current = performExpensiveCalculation();
+ }
+ }, []);
+
+ const performExpensiveCalculation = () => {
+ console.log("Performing expensive calculation...");
+ return Math.random() * 1000; // Simulating a heavy operation
+ };
+
+ return (
+
+
Input: {input}
+
Calculation Result: {calculationRef.current}
+
+
+ );
+};
+```
+
+Here, the expensive calculation only happens once when the component mounts, and the result is stored in `calculationRef`. This prevents unnecessary recalculations on re-renders, saving performance.
+
+### Event Listeners Optimization
+
+Event listeners (like scroll or resize) can cause performance issues if the handler functions re-create on every render. Using `useRef`, you can store a stable reference to the event handler, preventing it from being recreated:
+
+```jsx
+import { useRef, useEffect } from "react";
+
+const ScrollTracker = () => {
+ const scrollPositionRef = useRef(0);
+
+ useEffect(() => {
+ const handleScroll = () => {
+ scrollPositionRef.current = window.scrollY; // Store scroll position without re-rendering
+ console.log("Scroll position:", scrollPositionRef.current);
+ };
+
+ window.addEventListener("scroll", handleScroll);
+ return () => {
+ window.removeEventListener("scroll", handleScroll);
+ };
+ }, []);
+
+ return
Scroll down to see the effect
;
+};
+```
+
+In this example, `scrollPositionRef` stores the current scroll position without causing re-renders. This approach optimizes performance by reducing unnecessary renders while tracking the scroll position.
+
## Conclusion
In this article, we discussed how to create refs using the `useRef` hook and the `createRef` function. The `useRef` hook takes an initial value as argument and returns a ref object. You can update the ref object by modifying the ref object's `current` property.