Hooks and effects
Why Effects run twice in development
Treat development remounting as a test that exposes missing cleanup instead of adding a flag to hide the second call.
Strict Mode adds development checks that expose unsafe rendering and missing Effect cleanup.
For an Effect, React may run this sequence in development:
- Start synchronization.
- Clean it up.
- Start it again.
This simulates leaving and returning to the screen. A correct Effect remains safe because cleanup fully stops the first synchronization.
Do not hide the second run with a ref flag:
if (hasRun.current) return
hasRun.current = true
That can hide the warning while leaving the real remount bug. If the user navigates away and back, the component still needs to reconnect correctly.
Fix the pair instead:
useEffect(() => {
const connection = createConnection(roomId)
connection.connect()
return () => connection.disconnect()
}, [roomId])
Operations such as purchases and form submissions belong in event handlers, where a specific action caused them. Server endpoints for important operations should also handle retries and duplicates safely.
Strict Mode behavior is development-only, but the bugs it reveals are real.
Log connect and disconnect calls while changing rooms and mounting the component. Every started connection should have a matching cleanup.
Lesson completed