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.
This commit is contained in:
Riad Developer 2026-06-30 03:34:09 -07:00
parent 65b677181e
commit 1fce87c4c6
No known key found for this signature in database
3 changed files with 17 additions and 3 deletions

View File

@ -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();

View File

@ -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()) {

View File

@ -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<string | null>(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) {
if (currentUser.id !== lastFetchedUserIdRef.current) {
fetchProfile(currentUser.id);
}
} else {
lastFetchedUserIdRef.current = null;
setProfile(null);
setAccount(null);
setProfileLoading(false);