From 2b2460dbdbb3c10d330cd1175f68befbefabedfa Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Mon, 2 Jun 2025 08:48:32 +0430 Subject: [PATCH] fix(useLocalStorage): stabilize initialValue handling to prevent unnecessary re-renders --- frontend/src/hooks/useLocalStorage.ts | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/frontend/src/hooks/useLocalStorage.ts b/frontend/src/hooks/useLocalStorage.ts index f71e2676ba..aded8d96ce 100644 --- a/frontend/src/hooks/useLocalStorage.ts +++ b/frontend/src/hooks/useLocalStorage.ts @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; /** * A React hook for interacting with localStorage. @@ -17,11 +17,23 @@ export function useLocalStorage( key: string, initialValue: T | (() => T), ): [T, (value: T | ((prevState: T) => T)) => void, () => void] { + // Stabilize the initialValue to prevent unnecessary re-renders + const initialValueRef = useRef T)>(initialValue); + + // Update the ref if initialValue changes (for cases where it's intentionally dynamic) + useEffect(() => { + if (initialValueRef.current !== initialValue) { + initialValueRef.current = initialValue; + } + }, [initialValue]); + // This function resolves the initialValue if it's a function, // and handles potential errors during localStorage access or JSON parsing. const readValueFromStorage = useCallback((): T => { const resolvedInitialValue = - initialValue instanceof Function ? initialValue() : initialValue; + initialValueRef.current instanceof Function + ? (initialValueRef.current as () => T)() + : initialValueRef.current; try { const item = window.localStorage.getItem(key); @@ -34,7 +46,7 @@ export function useLocalStorage( console.warn(`Error reading localStorage key "${key}":`, error); } return resolvedInitialValue; - }, [key, initialValue]); + }, [key]); // Initialize state by reading from localStorage. const [storedValue, setStoredValue] = useState(readValueFromStorage); @@ -65,12 +77,14 @@ export function useLocalStorage( window.localStorage.removeItem(key); // Reset state to the (potentially resolved) initialValue. setStoredValue( - initialValue instanceof Function ? initialValue() : initialValue, + initialValueRef.current instanceof Function + ? (initialValueRef.current as () => T)() + : initialValueRef.current, ); } catch (error) { console.warn(`Error removing localStorage key "${key}":`, error); } - }, [key, initialValue]); + }, [key]); // useEffect to update the storedValue if the key changes, // or if the initialValue prop changes causing readValueFromStorage to change.