mirror of
https://github.com/dergigi/boris.git
synced 2026-02-14 11:34:29 +01:00
fix(reading-position): fix infinite loop causing spam saves
The root cause was scheduleSave being in the scroll effect's dependency array. Even though scheduleSave had an empty dependency array, React still saw it as a dependency and re-ran the effect constantly, causing unmount/remount loops and triggering flush-on-unmount repeatedly. Solution: Store scheduleSave in a ref (scheduleSaveRef) and call it via the ref in the scroll handler. This removes scheduleSave from the effect dependencies while still allowing the scroll handler to access the latest version. This fixes the "Maximum update depth exceeded" error and stops the spam saves.
This commit is contained in:
@@ -31,6 +31,7 @@ export const useReadingPosition = ({
|
||||
const suppressUntilRef = useRef<number>(0)
|
||||
const syncEnabledRef = useRef(syncEnabled)
|
||||
const onSaveRef = useRef(onSave)
|
||||
const scheduleSaveRef = useRef<((pos: number) => void) | null>(null)
|
||||
|
||||
// Keep refs in sync with props
|
||||
useEffect(() => {
|
||||
@@ -91,6 +92,11 @@ export const useReadingPosition = ({
|
||||
}, DEBOUNCE_MS)
|
||||
}, [])
|
||||
|
||||
// Store scheduleSave in ref for use in scroll handler
|
||||
useEffect(() => {
|
||||
scheduleSaveRef.current = scheduleSave
|
||||
}, [scheduleSave])
|
||||
|
||||
// Immediate save function
|
||||
const saveNow = useCallback(() => {
|
||||
if (!syncEnabledRef.current || !onSaveRef.current) return
|
||||
@@ -143,7 +149,7 @@ export const useReadingPosition = ({
|
||||
|
||||
// Schedule auto-save if sync is enabled (unless suppressed)
|
||||
if (Date.now() >= suppressUntilRef.current) {
|
||||
scheduleSave(clampedProgress)
|
||||
scheduleSaveRef.current?.(clampedProgress)
|
||||
} else {
|
||||
const remainingMs = suppressUntilRef.current - Date.now()
|
||||
console.log(`[reading-position] [${new Date().toISOString()}] 🛡️ Save suppressed (${remainingMs}ms remaining) at ${Math.round(clampedProgress * 100)}%`)
|
||||
@@ -207,7 +213,7 @@ export const useReadingPosition = ({
|
||||
clearTimeout(completionTimerRef.current)
|
||||
}
|
||||
}
|
||||
}, [enabled, onPositionChange, onReadingComplete, readingCompleteThreshold, scheduleSave, completionHoldMs])
|
||||
}, [enabled, onPositionChange, onReadingComplete, readingCompleteThreshold, completionHoldMs])
|
||||
|
||||
// Reset reading complete state when enabled changes
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user