Files
Account/src/features/profile/providers/ProfileProvider.tsx
2025-08-21 14:51:56 +03:30

63 lines
1.8 KiB
TypeScript

import { useApi } from '@/hooks/useApi';
import { fetchProfile } from '../api/settingsApi';
import { useCallback, useRef, useMemo, type ReactNode } from 'react';
import { ProfileContext } from '../contexts/ProfileContext';
import type { GetProfileApiResponse } from '../types/settingsApiType';
export const ProfileProvider = ({ children }: { children: ReactNode }) => {
const profileCache = useRef<GetProfileApiResponse | null>(null);
const pendingRequestRef = useRef<Promise<
GetProfileApiResponse | undefined
> | null>(null);
const { loading: isLoadingProfile, execute } = useApi(fetchProfile);
const refetchProfile = useCallback(
async (options?: {
force?: boolean;
}): Promise<GetProfileApiResponse | undefined> => {
// If forcing a refetch, clear the cache first
if (options?.force) {
profileCache.current = null;
}
// Return cached data if it exists
if (profileCache.current) {
return profileCache.current;
}
if (pendingRequestRef.current) {
return pendingRequestRef.current;
}
// If no request is pending, start a new one and store its promise
try {
pendingRequestRef.current = execute();
const result = await pendingRequestRef.current;
// Update cache on success
if (result?.success) {
profileCache.current = result;
}
return result;
} finally {
// Clear the pending request ref once the request is complete
pendingRequestRef.current = null;
}
},
[execute],
);
const value = useMemo(
() => ({
isLoadingProfile,
refetchProfile,
}),
[isLoadingProfile, refetchProfile],
);
return (
<ProfileContext.Provider value={value}>{children}</ProfileContext.Provider>
);
};