- #react
- #useeffect
- #strict-mode
Tại sao useEffect chạy 2 lần trong dev (và tại sao điều đó tốt)
Khi migrate sang React 18+ (và bây giờ React 19), useEffect của bạn sẽ chạy 2 lần trong development. Không phải bug — đây là React Strict Mode cố tình exercise cleanup logic của effect để lộ bug sớm.
Chuyện gì đang thực sự xảy ra
Trong Strict Mode, React mount → unmount → remount mọi component một lần trong dev. Console hiện ra pattern:
useEffect(() => {
console.log("mounted");
return () => console.log("cleanup");
}, []);
// Dev console: "mounted" → "cleanup" → "mounted"Production behavior không đổi — Strict Mode chỉ chạy trong dev.
Tại sao React làm vậy
React tương lai có thể preserve component state khi unmount/remount (router transitions, suspense boundaries, fiber-aware features). Strict Mode test cleanup logic của bạn HÔM NAY để refactor MAI không silent fail.
Fix: viết cleanup đúng
Nếu effect có side effect — subscription, timer, fetch — luôn return cleanup function. Nếu effect "break" trong Strict Mode, nó có thể đang leak resource trong production luôn.
Cần inspect stale state? Paste props của component vào JSON Formatter để thấy shape mismatch.