The new react-hooks lint rule "Calling setState synchronously within an effect can trigger cascading renders" flagged real anti-patterns in four spots. Refactored each per the rule's intent (derive during render, or use useSyncExternalStore for external subscriptions). 1. hooks/useMediaQuery.ts — replaced the useState + useEffect pair with useSyncExternalStore. That's the canonical React hook for subscribing to external stores (matchMedia in this case) without mirroring into local state via an effect. Snapshot/getServerSnapshot pair preserves the SSR-safe behaviour. 2. components/network/nodes/DeviceNode.tsx — the prop-sync useEffect that copied nodeData.label into labelValue was redundant. labelValue is the EDIT BUFFER; while not editing, the displayed span now reads nodeData.label directly. The buffer is initialized only when an edit session starts (onDoubleClick). 3. components/network/nodes/GroupNode.tsx — same pattern, same fix. 4. components/dashboard/TicketQueue.tsx — the setTickets([]) + setLoading(true) + fetchTickets() chain in the effect was the cascade. Pushed those writes inside fetchTickets (after the function boundary, so they batch with the eventual setTickets(result)). Added a request-id ref so a slow first response can't overwrite a fast second one. Frontend lint: 20 errors → 0 errors. tsc -b clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
7.7 KiB
7.7 KiB