우선 StrictMode란?
개발 모드에서 StrictMode가 활성화되면 리렌더링이 두 번 실행된다.
이는 StrictMode의 의도된 동작으로, 리렌더링 과정에서 발생할 수 있는 잠재적인 버그를 조기에 발견하기 위한 장치다.
다만, 비즈니스 코드 작성 중에 디버깅 과정에서 console.log 출력이 예상과 다르게 나타나는 현상이 있었다.
- 동기 함수의 로그는 한 번만 출력됨
- 비동기 함수의 로그는 두 번 출력됨
예시 코드
아래는 위 상황을 간단히 표현한 코드이다.
import { useMemo } from 'react';
let num = 0;
function App() {
useMemo(() => {
const id = num++;
console.log(id);
setTimeout(() => {
console.log(`${id} in timeout`);
}, 1000);
}, []);
return null;
}
export default App;
개발 모드이므로 StrictMode가 동작하는 상황이다.
예상 VS 실제 결과
처음엔 두 번 실행되니 아래처럼 출력될 거라 생각했다.
0
1
0 in timeout
1 in timeout
하지만 실제로는 전혀 달랐다.
동기 로그(0)는 한 번만 나오고, setTimeout 내부 로그만 두 번찍힌 것이다.

원인
처음에는 StrictMode 버그인가? 이벤트 루프 문제인가? 등 여러 가설을 세워봤지만, 결론은 단순했다.
React DevTools에서 제공하는 "중복 로그 제거(Deduplication)" 기능 때문이었다.

이 기능이 켜져 있으면 StrictMode로 인해 발생한 중복 로그가 한 번만 표시된다.
(동기 로그는 한 번만 보이고, 비동기 로그는 DevTools가 잡아내지 못해 두 번 찍힌 것이다.)
이 옵션을 끄고 다시 실행하면 예상대로 모든 로그가 두 번 출력된다.

왜 이런 기능이 있을까?
React 팀에서는 “StrictMode가 일부러 두 번 실행하지만, 개발자가 디버깅할 때 혼란스럽지 않도록 콘솔에는 최대한 한 번만 보여주자” 라는 취지로 이 기능을 넣은 것이다.
리액트를 회사에서 사용한 지도 어느덧 2년이 넘었지만, 여전히 배워야 할 것이 많다는 걸 느낀다.
이번 문제를 마주했을 때는 그동안의 지식이 무너지는 듯했지만, 다행히도 버그가 아닌 기능이었다는 점에서 안도할 수 있었다.
앞으로는 React가 어떻게 log를 dedup하는지 코드까지 직접 분석해보며 더 깊이 이해해보고자 한다.
'개발' 카테고리의 다른 글
| [번역] 소프트웨어 엔지니어링에서 좋은 취향은 뭘까? (0) | 2025.11.09 |
|---|---|
| [번역] 심층 분석: Microtasks와 Javascript 실행 환경 (0) | 2025.10.26 |
| 교보문고 MCP를 만들면서, Chrome Devtools Protocol을 사용해봤다. (1) | 2025.08.16 |
| redis clustering, tunneling을 통해 접근하는 방법 with Node.js (2) | 2025.08.09 |
| AI와 함께 라이브러리를 만들어봤다. (0) | 2025.06.05 |