From 1fce87c4c60a07b6893f105ad5ea632cfd04cdfd Mon Sep 17 00:00:00 2001 From: Riad Developer <147613731+RiadDeveloper@users.noreply.github.com> Date: Tue, 30 Jun 2026 03:34:09 -0700 Subject: [PATCH] Prevent redundant profile fetches on refresh Replace `user` object with `user?.id` in dependency arrays to prevent unnecessary re-renders. Add `lastFetchedUserIdRef` to track the user ID for successfully initiated profile fetches, preventing redundant API calls when the window refocuses or the auth token is refreshed. --- src/components/settings/settings-overview.tsx | 2 +- src/components/settings/whatsapp-config.tsx | 2 +- src/hooks/use-auth.tsx | 16 +++++++++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/components/settings/settings-overview.tsx b/src/components/settings/settings-overview.tsx index fff559a..2b61cf8 100644 --- a/src/components/settings/settings-overview.tsx +++ b/src/components/settings/settings-overview.tsx @@ -135,7 +135,7 @@ export function SettingsOverview({ return () => { cancelled = true; }; - }, [user, accountId, canManageMembers]); + }, [user?.id, accountId, canManageMembers]); const displayName = profile?.full_name || profile?.email || 'Your account'; const initial = (profile?.full_name || profile?.email || 'U').charAt(0).toUpperCase(); diff --git a/src/components/settings/whatsapp-config.tsx b/src/components/settings/whatsapp-config.tsx index e6e4023..f07f843 100644 --- a/src/components/settings/whatsapp-config.tsx +++ b/src/components/settings/whatsapp-config.tsx @@ -168,7 +168,7 @@ export function WhatsAppConfig() { return; } fetchConfig(accountId); - }, [authLoading, profileLoading, user, accountId, fetchConfig]); + }, [authLoading, profileLoading, user?.id, accountId, fetchConfig]); async function handleSave() { if (!phoneNumberId.trim()) { diff --git a/src/hooks/use-auth.tsx b/src/hooks/use-auth.tsx index 47284dd..c14434b 100644 --- a/src/hooks/use-auth.tsx +++ b/src/hooks/use-auth.tsx @@ -7,6 +7,7 @@ import { useState, useCallback, useMemo, + useRef, type ReactNode, } from "react"; import { createClient } from "@/lib/supabase/client"; @@ -121,12 +122,18 @@ export function AuthProvider({ children }: { children: ReactNode }) { // window they're in — see the type doc above. const [profileLoading, setProfileLoading] = useState(true); + // Tracks the user ID we've successfully initiated/completed fetching + // a profile for. This prevents redundant re-fetches and toggling + // profileLoading back to true on window focus events/token refresh. + const lastFetchedUserIdRef = useRef(null); + // Shared across init, auth-state-change listener, and the exposed // refreshProfile() callback. Reads the current session's user id and // pulls the matching profile row along with its account summary. const fetchProfile = useCallback(async (userId: string) => { const supabase = createClient(); setProfileLoading(true); + lastFetchedUserIdRef.current = userId; try { const { data, error } = await supabase .from("profiles") @@ -143,6 +150,7 @@ export function AuthProvider({ children }: { children: ReactNode }) { hint: error.hint, code: error.code, }); + lastFetchedUserIdRef.current = null; return; } @@ -206,9 +214,12 @@ export function AuthProvider({ children }: { children: ReactNode }) { account_role: accountRole, }); setAccount(accountRow); + } else { + lastFetchedUserIdRef.current = null; } } catch (err) { console.error("[AuthProvider] fetchProfile threw:", err); + lastFetchedUserIdRef.current = null; } finally { setProfileLoading(false); } @@ -269,8 +280,11 @@ export function AuthProvider({ children }: { children: ReactNode }) { setUser(currentUser); if (currentUser) { - fetchProfile(currentUser.id); + if (currentUser.id !== lastFetchedUserIdRef.current) { + fetchProfile(currentUser.id); + } } else { + lastFetchedUserIdRef.current = null; setProfile(null); setAccount(null); setProfileLoading(false);