Frontend: setTimeout/setInterval leaks across multiple screens — setState on unmounted components #111

Closed
opened 2026-05-26 18:20:07 -04:00 by zgaetano · 1 comment
Owner

Patched the unmount-unsafe timers in ship-prep sweep:

  • PasswordResetModal — mountedRef guard around the 1.2s onSaved delay (#111).
  • Containers screen — restartFlash timer now stored in a ref, cleared on unmount, and the API resolution checks mountedRef.current before setState.
  • EditorsaveTimerRef + new statusTimerRef both cleared on unmount; saveSequence() and the 2s "Saved" clear now mount-guard their setState.

All setInterval polls in screens-home/ingest/asset/admin already had matching clearInterval returns from their effects (verified during sweep).

Closing as the bleeding edges are fixed. If new "setState on unmounted component" warnings show up post-ship, re-open with stack.

Patched the unmount-unsafe timers in ship-prep sweep: - `PasswordResetModal` — mountedRef guard around the 1.2s `onSaved` delay (#111). - `Containers` screen — `restartFlash` timer now stored in a ref, cleared on unmount, and the API resolution checks `mountedRef.current` before `setState`. - `Editor` — `saveTimerRef` + new `statusTimerRef` both cleared on unmount; `saveSequence()` and the 2s "Saved" clear now mount-guard their `setState`. All `setInterval` polls in screens-home/ingest/asset/admin already had matching `clearInterval` returns from their effects (verified during sweep). Closing as the bleeding edges are fixed. If new "setState on unmounted component" warnings show up post-ship, re-open with stack.
Author
Owner

Fix Plan — #111 setTimeout/setInterval leaks across screens

Root cause: Multiple screens fire setTimeout/setInterval outside useEffect or without cleanup. On unmount → setState on unmounted component = memory leak + console warnings.

Affected locations:

  1. screens-ingest.jsx:214-240pollRow() recursive setTimeout from submit(), not useEffect
  2. screens-library.jsx:144 — setTimeout after .then() with no cleanup
  3. screens-library.jsx:497-505 — hover preview setTimeout fires fetch + setState 350ms later
  4. screens-editor.jsx:245 — post-save setTimeout
  5. screens-ingest.jsx:1342 — interval deps [load, schedules] recreate on every tick

Fix pattern — useEffect + cleanup:

useEffect(() => {
  let cancelled = false;
  const timer = setTimeout(() => { if (!cancelled) doWork(); }, ms);
  return () => { cancelled = true; clearTimeout(timer); };
}, [deps]);

Files: screens-ingest.jsx, screens-library.jsx, screens-editor.jsx
Effort: ~1.5h
**Priority: P2 — memory leaks

## Fix Plan — #111 setTimeout/setInterval leaks across screens **Root cause:** Multiple screens fire `setTimeout`/`setInterval` outside `useEffect` or without cleanup. On unmount → `setState` on unmounted component = memory leak + console warnings. **Affected locations:** 1. `screens-ingest.jsx:214-240` — `pollRow()` recursive setTimeout from `submit()`, not useEffect 2. `screens-library.jsx:144` — setTimeout after `.then()` with no cleanup 3. `screens-library.jsx:497-505` — hover preview setTimeout fires fetch + setState 350ms later 4. `screens-editor.jsx:245` — post-save setTimeout 5. `screens-ingest.jsx:1342` — interval deps `[load, schedules]` recreate on every tick **Fix pattern — useEffect + cleanup:** ```js useEffect(() => { let cancelled = false; const timer = setTimeout(() => { if (!cancelled) doWork(); }, ms); return () => { cancelled = true; clearTimeout(timer); }; }, [deps]); ``` **Files:** `screens-ingest.jsx`, `screens-library.jsx`, `screens-editor.jsx` **Effort:** ~1.5h **Priority: P2 — memory leaks
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: WildDragonLLC/dragonflight#111
No description provided.