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 () => { return () => {
cancelled = true; cancelled = true;
}; };
}, [user, accountId, canManageMembers]); }, [user?.id, accountId, canManageMembers]);
const displayName = profile?.full_name || profile?.email || 'Your account'; const displayName = profile?.full_name || profile?.email || 'Your account';
const initial = (profile?.full_name || profile?.email || 'U').charAt(0).toUpperCase(); const initial = (profile?.full_name || profile?.email || 'U').charAt(0).toUpperCase();

View File

@ -168,7 +168,7 @@ export function WhatsAppConfig() {
return; return;
} }
fetchConfig(accountId); fetchConfig(accountId);
}, [authLoading, profileLoading, user, accountId, fetchConfig]); }, [authLoading, profileLoading, user?.id, accountId, fetchConfig]);
async function handleSave() { async function handleSave() {
if (!phoneNumberId.trim()) { if (!phoneNumberId.trim()) {

View File

@ -7,6 +7,7 @@ import {
useState, useState,
useCallback, useCallback,
useMemo, useMemo,
useRef,
type ReactNode, type ReactNode,
} from "react"; } from "react";
import { createClient } from "@/lib/supabase/client"; 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. // window they're in — see the type doc above.
const [profileLoading, setProfileLoading] = useState(true); 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 // Shared across init, auth-state-change listener, and the exposed
// refreshProfile() callback. Reads the current session's user id and // refreshProfile() callback. Reads the current session's user id and
// pulls the matching profile row along with its account summary. // pulls the matching profile row along with its account summary.
const fetchProfile = useCallback(async (userId: string) => { const fetchProfile = useCallback(async (userId: string) => {
const supabase = createClient(); const supabase = createClient();
setProfileLoading(true); setProfileLoading(true);
lastFetchedUserIdRef.current = userId;
try { try {
const { data, error } = await supabase const { data, error } = await supabase
.from("profiles") .from("profiles")
@ -143,6 +150,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
hint: error.hint, hint: error.hint,
code: error.code, code: error.code,
}); });
lastFetchedUserIdRef.current = null;
return; return;
} }
@ -206,9 +214,12 @@ export function AuthProvider({ children }: { children: ReactNode }) {
account_role: accountRole, account_role: accountRole,
}); });
setAccount(accountRow); setAccount(accountRow);
} else {
lastFetchedUserIdRef.current = null;
} }
} catch (err) { } catch (err) {
console.error("[AuthProvider] fetchProfile threw:", err); console.error("[AuthProvider] fetchProfile threw:", err);
lastFetchedUserIdRef.current = null;
} finally { } finally {
setProfileLoading(false); setProfileLoading(false);
} }
@ -269,8 +280,11 @@ export function AuthProvider({ children }: { children: ReactNode }) {
setUser(currentUser); setUser(currentUser);
if (currentUser) { if (currentUser) {
fetchProfile(currentUser.id); if (currentUser.id !== lastFetchedUserIdRef.current) {
fetchProfile(currentUser.id);
}
} else { } else {
lastFetchedUserIdRef.current = null;
setProfile(null); setProfile(null);
setAccount(null); setAccount(null);
setProfileLoading(false); setProfileLoading(false);