학습 공간 개념 · 판단 · 실험

Frontend Performance Lab

동작 실습 · REACT

+3 버튼을 눌렀는데 왜 수량은 1만 늘어날까요?

setCount를 똑같이 세 번 호출했는데 수량은 왜 다를까요? 두 장바구니 버튼을 직접 눌러 비교해 보세요.

미리 알면 좋아요 · JavaScript 함수와 React useState의 기본 사용법

01 개념 이해

setCount를 연속으로 호출하면 어떻게 처리될까요?

화면에 보이는 수량이 count라면, setCount는 React에 “다음 렌더링의 수량을 바꿔 주세요”라고 요청하는 함수입니다. 요청을 보냈다고 해서 지금 실행 중인 핸들러 함수 안의 count 변수까지 즉시 바뀌지는 않습니다.

setCount에 다음 숫자를 직접 전달할 수도 있고, “이전 결과에 1을 더해 주세요”라는 업데이터 함수를 전달할 수도 있습니다. 한 이벤트 안에서 세 번 연속 호출했을 때 두 방식의 결과를 비교해 보세요.

장바구니 상황에 적용하기 →

02 상황과 예상

상품 3개를 한 번에 담는 버튼

장바구니에서 +3 버튼을 만들며 setCount를 세 번 호출했습니다. 값을 직접 전달하는 방법과 업데이터 함수를 전달하는 방법은 결과가 어떻게 다를까요?

비교 조건
다음 수량 값을 직접 전달하기 vs 이전 결과에 1을 더하는 업데이터 함수 전달하기
고정 조건
초기 수량 0개, 클릭 한 번당 setCount 3회 호출 (두 장바구니는 서로 독립적)
확인할 지표
클릭 전후 수량과 변화량. 다음 클릭 결과를 먼저 예상해 보거나 바로 실행할 수 있습니다.
실제 버튼으로 확인하기 →

03 실행과 관찰

두 장바구니에 직접 담아 보세요

각 패널을 한 번씩 실행한 뒤 한 번 더 눌러 보세요. 실행한 패널 아래에 코드 풀이 해설이 나타납니다.

값을 직접 전달하기

setCount(count + 1);
setCount(count + 1);
setCount(count + 1);

현재 수량 0개

아직 실행하지 않았습니다. 두 장바구니는 서로 독립적으로 동작합니다.

업데이터 함수 전달하기

setCount(n => n + 1);
setCount(n => n + 1);
setCount(n => n + 1);

현재 수량 0개

아직 실행하지 않았습니다. 두 장바구니는 서로 독립적으로 동작합니다.

두 수량·실행 횟수·예상·관찰 결과·해설·적용 질문 답안을 모두 초기화합니다.

상태 업데이트를 모아 처리하는 방식

React는 이벤트 핸들러가 끝난 뒤 예약된 업데이트를 한꺼번에 처리합니다(배칭, Batching). 다음 화면 구조를 계산하는 렌더(Render) 단계와 실제 DOM에 반영하는 커밋(Commit) 단계도 분리되어 있습니다.

업데이터 함수는 이전 상태를 받아 다음 상태만 계산하는 순수 함수여야 합니다. 개발 모드(Strict Mode)에서는 순수성을 검증하기 위해 두 번 호출될 수 있으므로, 그 안에서 네트워크 통신을 하거나 외부 상태를 직접 바꾸지 마세요.

이 실습은 별도 실행 기록을 저장하지 않으며 새로고침하면 초기화됩니다.

실제로 실행하는 코드 보기

위 버튼이 실제로 호출하는 replaceThree, updateThree 함수의 원본 코드입니다.

updates.ts
import type { Dispatch, SetStateAction } from "react";

// Each button invokes one of these functions in its React click handler.
export function replaceThree(count: number, setCount: Dispatch<SetStateAction<number>>) {
  setCount(count + 1);
  setCount(count + 1);
  setCount(count + 1);
}

export function updateThree(setCount: Dispatch<SetStateAction<number>>) {
  setCount(n => n + 1);
  setCount(n => n + 1);
  setCount(n => n + 1);
}
TypeScript · 읽기 전용14줄