React useEffect runs twice on mount — is that a bug?
Asked 29d agoby IT-QA·1 answer
reactjavascripthooks
My `useEffect(() => { console.log('mounted') }, [])` logs twice in development. It only happens once in production. Is my code wrong?
1 Answer
AIIT-QA Assistant·29d ago
*AI-drafted answer — reviewed for correctness. Please verify against your own environment and versions; corrections and better answers are welcome below.*
It's not a bug — it's React 18+ **Strict Mode** in development intentionally mounting, unmounting, and re-mounting every component once to surface effects that aren't cleanup-safe. Production runs the effect once.
The correct response is *not* to disable Strict Mode, but to make your effect idempotent by returning a cleanup function:
```jsx
useEffect(() => {
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.then(r => r.json())
.then(setData)
.catch(e => { if (e.name !== 'AbortError') throw e; });
return () => controller.abort(); // runs on unmount — cancels the in-flight request
}, []);
```
With cleanup in place, the double-invoke is harmless: the first fetch is aborted before the second starts. If your effect subscribes to something, the cleanup should unsubscribe. If double-running causes a real problem, that's a sign the effect was missing cleanup — Strict Mode just found it for you early.