mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 12:11:21 -05:00
Fix realtime subscription loop
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEffect, useState, useRef, useCallback } from 'react';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { RealtimeChannel } from '@supabase/supabase-js';
|
||||
|
||||
@@ -22,9 +22,15 @@ export const useRealtimeModerationStats = (options: UseRealtimeModerationStatsOp
|
||||
flaggedContent: 0,
|
||||
});
|
||||
const [channel, setChannel] = useState<RealtimeChannel | null>(null);
|
||||
const [updateTimer, setUpdateTimer] = useState<NodeJS.Timeout | null>(null);
|
||||
const updateTimerRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const onStatsChangeRef = useRef(onStatsChange);
|
||||
|
||||
const fetchStats = async () => {
|
||||
// Update ref when callback changes
|
||||
useEffect(() => {
|
||||
onStatsChangeRef.current = onStatsChange;
|
||||
}, [onStatsChange]);
|
||||
|
||||
const fetchStats = useCallback(async () => {
|
||||
try {
|
||||
const [submissionsResult, reportsResult, reviewsResult] = await Promise.all([
|
||||
supabase
|
||||
@@ -48,19 +54,18 @@ export const useRealtimeModerationStats = (options: UseRealtimeModerationStatsOp
|
||||
};
|
||||
|
||||
setStats(newStats);
|
||||
onStatsChange?.(newStats);
|
||||
onStatsChangeRef.current?.(newStats);
|
||||
} catch (error) {
|
||||
console.error('Error fetching moderation stats:', error);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const debouncedFetchStats = () => {
|
||||
if (updateTimer) {
|
||||
clearTimeout(updateTimer);
|
||||
const debouncedFetchStats = useCallback(() => {
|
||||
if (updateTimerRef.current) {
|
||||
clearTimeout(updateTimerRef.current);
|
||||
}
|
||||
const timer = setTimeout(fetchStats, debounceMs);
|
||||
setUpdateTimer(timer);
|
||||
};
|
||||
updateTimerRef.current = setTimeout(fetchStats, debounceMs);
|
||||
}, [fetchStats, debounceMs]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled) return;
|
||||
@@ -115,12 +120,12 @@ export const useRealtimeModerationStats = (options: UseRealtimeModerationStatsOp
|
||||
|
||||
return () => {
|
||||
console.log('Cleaning up moderation stats realtime subscription');
|
||||
if (updateTimer) {
|
||||
clearTimeout(updateTimer);
|
||||
if (updateTimerRef.current) {
|
||||
clearTimeout(updateTimerRef.current);
|
||||
}
|
||||
supabase.removeChannel(realtimeChannel);
|
||||
};
|
||||
}, [enabled]);
|
||||
}, [enabled, fetchStats, debouncedFetchStats]);
|
||||
|
||||
return { stats, refresh: fetchStats };
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEffect, useState, useRef } from 'react';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { RealtimeChannel } from '@supabase/supabase-js';
|
||||
|
||||
@@ -12,6 +12,14 @@ export const useRealtimeSubmissionItems = (options: UseRealtimeSubmissionItemsOp
|
||||
const { submissionId, onUpdate, enabled = true } = options;
|
||||
const [channel, setChannel] = useState<RealtimeChannel | null>(null);
|
||||
|
||||
// Use ref to store latest callback without triggering re-subscriptions
|
||||
const onUpdateRef = useRef(onUpdate);
|
||||
|
||||
// Update ref when callback changes
|
||||
useEffect(() => {
|
||||
onUpdateRef.current = onUpdate;
|
||||
}, [onUpdate]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled || !submissionId) return;
|
||||
|
||||
@@ -27,7 +35,7 @@ export const useRealtimeSubmissionItems = (options: UseRealtimeSubmissionItemsOp
|
||||
},
|
||||
(payload) => {
|
||||
console.log('Submission item updated:', payload);
|
||||
onUpdate?.(payload);
|
||||
onUpdateRef.current?.(payload);
|
||||
}
|
||||
)
|
||||
.subscribe((status) => {
|
||||
@@ -40,7 +48,7 @@ export const useRealtimeSubmissionItems = (options: UseRealtimeSubmissionItemsOp
|
||||
console.log('Cleaning up submission items realtime subscription');
|
||||
supabase.removeChannel(realtimeChannel);
|
||||
};
|
||||
}, [submissionId, enabled, onUpdate]);
|
||||
}, [submissionId, enabled]);
|
||||
|
||||
return { channel };
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEffect, useState, useRef } from 'react';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { RealtimeChannel } from '@supabase/supabase-js';
|
||||
|
||||
@@ -13,6 +13,18 @@ export const useRealtimeSubmissions = (options: UseRealtimeSubmissionsOptions =
|
||||
const { onInsert, onUpdate, onDelete, enabled = true } = options;
|
||||
const [channel, setChannel] = useState<RealtimeChannel | null>(null);
|
||||
|
||||
// Use refs to store latest callbacks without triggering re-subscriptions
|
||||
const onInsertRef = useRef(onInsert);
|
||||
const onUpdateRef = useRef(onUpdate);
|
||||
const onDeleteRef = useRef(onDelete);
|
||||
|
||||
// Update refs when callbacks change
|
||||
useEffect(() => {
|
||||
onInsertRef.current = onInsert;
|
||||
onUpdateRef.current = onUpdate;
|
||||
onDeleteRef.current = onDelete;
|
||||
}, [onInsert, onUpdate, onDelete]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled) return;
|
||||
|
||||
@@ -27,7 +39,7 @@ export const useRealtimeSubmissions = (options: UseRealtimeSubmissionsOptions =
|
||||
},
|
||||
(payload) => {
|
||||
console.log('Submission inserted:', payload);
|
||||
onInsert?.(payload);
|
||||
onInsertRef.current?.(payload);
|
||||
}
|
||||
)
|
||||
.on(
|
||||
@@ -39,7 +51,7 @@ export const useRealtimeSubmissions = (options: UseRealtimeSubmissionsOptions =
|
||||
},
|
||||
(payload) => {
|
||||
console.log('Submission updated:', payload);
|
||||
onUpdate?.(payload);
|
||||
onUpdateRef.current?.(payload);
|
||||
}
|
||||
)
|
||||
.on(
|
||||
@@ -51,7 +63,7 @@ export const useRealtimeSubmissions = (options: UseRealtimeSubmissionsOptions =
|
||||
},
|
||||
(payload) => {
|
||||
console.log('Submission deleted:', payload);
|
||||
onDelete?.(payload);
|
||||
onDeleteRef.current?.(payload);
|
||||
}
|
||||
)
|
||||
.subscribe((status) => {
|
||||
@@ -64,7 +76,7 @@ export const useRealtimeSubmissions = (options: UseRealtimeSubmissionsOptions =
|
||||
console.log('Cleaning up submissions realtime subscription');
|
||||
supabase.removeChannel(realtimeChannel);
|
||||
};
|
||||
}, [enabled, onInsert, onUpdate, onDelete]);
|
||||
}, [enabled]);
|
||||
|
||||
return { channel };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user