React를 공부하다 보면 이런 말을 자주 본다.
“React는 state를 스냅샷으로 다룬다.”
그런데 막상 보면 감이 잘 안 온다.
버튼을 누르면 값이 바뀌는데, 대체 뭐가 스냅샷이라는 걸까?
이 글에서는 다음을 정리한다:
스냅샷의 정확한 의미
state와 스냅샷의 차이
왜 setState를 여러 번 호출해도 1만 증가하는지
Virtual DOM과의 관계
React에서 스냅샷은 다음을 의미한다.
“컴포넌트가 렌더링되는 그 순간의 state/props 값 묶음”
중요한 점은:
state 자체가 스냅샷이 아니다.
렌더 시점에 사용되는 state 값이 스냅샷이다.
먼저 가장 단순한 예제를 보자.
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
);
}이 코드를 보면 우리는 보통 이렇게 생각한다.
count = 0
→ 버튼 클릭
→ count = 1
→ 다시 클릭
→ count = 2마치 count라는 하나의 변수가 계속 바뀌는 것처럼 보인다.
하지만 React 내부에서는 다르게 동작한다.
컴포넌트가 처음 실행된다.
Render #1
count = 0화면에는 0이 보인다.
이 시점의 count 값이 바로 첫 번째 스냅샷이다.
setCount(count + 1)이 실행된다.
여기서 중요한 점:
이 코드가 보고 있는 count는
현재 렌더(Render #1)의 값(0) 이다.
React는 이렇게 이해한다:
"다음 렌더에서 count를 1로 설정하자"React가 컴포넌트를 다시 실행한다.
Render #2
count = 1이건 기존 값이 수정된 게 아니라,
새로운 렌더가 생성된 것이다.
우리가 생각하는 모델:
count라는 변수 하나가 계속 변경됨React 실제 모델:
Render #1 → count = 0
Render #2 → count = 1
Render #3 → count = 2즉,
값이 변하는 게 아니라
렌더가 새로 만들어지는 것이다.
그리고 각 렌더는
자기만의 state 값(스냅샷)을 가진다.
다음 코드를 보자.
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);왜 3이 아니라 1만 증가할까?
이유는 간단하다.
count는 최신 state가 아니라
현재 렌더의 스냅샷 값이기 때문이다.
예를 들어 현재 렌더의 count가 0이라면:
setCount(0 + 1);
setCount(0 + 1);
setCount(0 + 1);React는 결국 “다음 state를 1로 설정”을 세 번 받는 셈이다.
setCount(prev => prev + 1);이 방식은:
스냅샷 값이 아니라
React의 업데이트 큐 기준으로 계산한다.
그래서 정상적으로 3이 증가한다.
정확히 구분하면 다음과 같다.
개념 | 의미 |
|---|---|
state | React 내부에 저장된 최신 상태 |
snapshot | 렌더 시점에 사용되는 고정된 상태 값 |
정리하면:
state는 시간에 따라 업데이트되지만
snapshot은 렌더 단위로 고정된다.
렌더 과정은 다음과 같다.
state 변경 요청
→ 새로운 스냅샷 생성
→ 컴포넌트 실행
→ Virtual DOM 생성
→ 이전 Virtual DOM과 비교
→ 실제 DOM 반영즉:
스냅샷은 입력값
Virtual DOM은 결과물
스냅샷이 Virtual DOM은 아니지만,
Virtual DOM을 만들기 위한 기반 데이터다.
이 구조 덕분에:
예측 가능한 렌더링
부작용 최소화
Concurrent Rendering 가능
이전 트리를 유지하면서 새 트리 계산 가능
만약 state가 직접 mutate됐다면
React 18의 동시성 모델은 거의 불가능했을 것이다.
React에서 스냅샷이란,
“렌더 시점에 고정된 state 값”이다.
상태가 변하는 것이 아니라,
새로운 렌더와 함께 새로운 스냅샷이 생성된다.