Refactor: Debounce effect fetches

This commit is contained in:
gpt-engineer-app[bot]
2025-10-13 01:45:05 +00:00
parent a5bf6d873e
commit 2661d65ab8

View File

@@ -128,6 +128,8 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
const fetchItemsRef = useRef<((silent?: boolean) => Promise<void>) | null>(null);
const FETCH_COOLDOWN_MS = 1000;
const EFFECT_DEBOUNCE_MS = 50; // Short debounce to let all effects settle
const effectFetchTimerRef = useRef<NodeJS.Timeout | null>(null);
// Store settings in refs to avoid re-creating fetchItems
const settingsRef = useRef(settings);
@@ -856,19 +858,26 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [user?.id]);
// Debounced fetch for effects - prevents race conditions
const debouncedEffectFetch = useCallback(() => {
if (effectFetchTimerRef.current) {
clearTimeout(effectFetchTimerRef.current);
}
effectFetchTimerRef.current = setTimeout(() => {
console.log('[Debounced Fetch] Executing after effects settled');
fetchItemsRef.current?.(true);
}, EFFECT_DEBOUNCE_MS);
}, []);
// Filter and tab changes trigger refetch
useEffect(() => {
if (!user || !initialFetchCompleteRef.current || isMountingRef.current) return;
console.log('[Filter/Tab Change] Refetching with:', {
tab: filters.activeTab,
entity: filters.debouncedEntityFilter,
status: filters.debouncedStatusFilter
});
console.log('[Filter/Tab Change] Queuing debounced fetch');
pagination.reset();
fetchItemsRef.current?.(true);
}, [filters.activeTab, filters.debouncedEntityFilter, filters.debouncedStatusFilter, user]);
debouncedEffectFetch();
}, [filters.activeTab, filters.debouncedEntityFilter, filters.debouncedStatusFilter, user, debouncedEffectFetch, pagination]);
// Sort changes trigger refetch
useEffect(() => {
@@ -876,20 +885,26 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
return;
}
console.log('[Sort Change] Refetching with:', {
field: sort.field,
direction: sort.direction
});
console.log('[Sort Change] Queuing debounced fetch');
pagination.reset();
fetchItemsRef.current?.(true);
}, [sort.field, sort.direction, user, pagination]);
debouncedEffectFetch();
}, [sort.field, sort.direction, user, pagination, debouncedEffectFetch]);
// Pagination changes trigger refetch
useEffect(() => {
if (!user || !initialFetchCompleteRef.current || pagination.currentPage === 1) return;
fetchItemsRef.current?.(true);
}, [pagination.currentPage, pagination.pageSize]);
debouncedEffectFetch();
}, [pagination.currentPage, pagination.pageSize, debouncedEffectFetch]);
// Cleanup effect timer on unmount
useEffect(() => {
return () => {
if (effectFetchTimerRef.current) {
clearTimeout(effectFetchTimerRef.current);
}
};
}, []);
// Polling effect (when realtime disabled)
useEffect(() => {