🐌 React Anti-Patterns & Race Conditions in useLearningProgress
Issue Description
The new src/hooks/useLearningProgress.ts hook suffers from two distinct anti-patterns:
- Cascading Renders: In the main
useEffect checking authentication, it invokes setCompletedNodes([]) and setLoading(false) synchronously when no user is present. This directly violates React guidelines and triggers unnecessary sequential render cycles.
- Redundant Optimistic UI: The
toggleNode function manually updates local state before sending the network request. Because Firestore's onSnapshot listener triggers instantly upon local writes (latency compensation), the manual local state management creates conflicting state updates and potential race conditions if the network request fails and reverts the state.
Impact
- Performance: The cascading renders degrade performance and trigger standard linter warnings (
react-hooks/set-state-in-effect).
- Reliability: Overlapping the custom optimistic UI logic with Firestore's native latency compensation creates brittle edge cases and redundant re-renders when toggling progress nodes.
Proposed Fix
- Initialize the default state conditionally before the
useEffect body to prevent the synchronous state update.
- Simplify
toggleNode to exclusively perform the setDoc operation. Rely entirely on the existing onSnapshot listener to handle both the immediate optimistic UI update and the confirmed server update automatically.
Suggested Labels
bug
performance
tech-debt
🐌 React Anti-Patterns & Race Conditions in
useLearningProgressIssue Description
The new
src/hooks/useLearningProgress.tshook suffers from two distinct anti-patterns:useEffectchecking authentication, it invokessetCompletedNodes([])andsetLoading(false)synchronously when no user is present. This directly violates React guidelines and triggers unnecessary sequential render cycles.toggleNodefunction manually updates local state before sending the network request. Because Firestore'sonSnapshotlistener triggers instantly upon local writes (latency compensation), the manual local state management creates conflicting state updates and potential race conditions if the network request fails and reverts the state.Impact
react-hooks/set-state-in-effect).Proposed Fix
useEffectbody to prevent the synchronous state update.toggleNodeto exclusively perform thesetDocoperation. Rely entirely on the existingonSnapshotlistener to handle both the immediate optimistic UI update and the confirmed server update automatically.Suggested Labels
bugperformancetech-debt