-
React의 State 업데이트 큐FE/React 2025. 10. 23. 14:13
🧑🏻💻React의 State 업데이트 큐(Queue)
🚀 Batch
React는 state 업데이트를 하기 전에 이벤트 핸들러의 모든 코드가 실행될 때까지 기다림
이를 통해 너무 많은
리렌더링이 발생하지 않고도 여러 컴포넌트에서 나온 다수의 state 변수를 업데이트 가능.하지만 이벤트 핸들러와 그 안에 있는 코드가 완료될 때까지 UI가 업데이트되지 않는다
따라서 React가 여러 상태 업데이트를 단일 리렌더링으로 그룹화하여 성능을 향상하는 것!!
🖥️ 예시 코드
import { useState } from 'react'; export default function Counter() { const [number, setNumber] = useState(0); return ( <> <h1>{number}</h1> <button onClick={() => { setNumber(number + 1); setNumber(number + 1); setNumber(number + 1); }}>+3</button> </> ) }🔍
setNumber(number + 1)를 3번 호출하게 되니깐 결과는 3이 되겠지?!?- 실제 값은
1이다.
💡 이유
- 각 렌더링의 state의 값은 고정되어 있어 첫 번째 렌더링의 이벤트 핸들러의 number의 값은 setNumber 를 몇 번을 호출하든지 항상 0!
🤔 각 렌더링의 state의 값은 고정 ??
렌더링은 React가 컴포넌트(함수)를 호출한다는 의미.
이 함수에서 반환하는 JSX는 시간상 UI의 스냅샷과 같아
prop,이벤트 핸들러,로컬 변수는 모두 렌더링 당시의 state를 사용해 계산즉, state를 설정하면 다음 렌더링에 대해서만 변경이 된다!
- 위 예시를 예시로 설명해보면 다음과 같아요.
첫 번째 렌더링에서의 number의 값은 0
<button onClick={() => { setNumber(number + 1); setNumber(number + 1); setNumber(number + 1); }}>+3</button>setNumber(number + 1)- number는 0, React는 다음 렌더링에서 number를 1로 변경할 준비
setNumber(number + 1)- number는 0, React는 다음 렌더링에서 number를 1로 변경할 준비
setNumber(number + 1)- number는 0, React는 다음 렌더링에서 number를 1로 변경할 준비
이렇게 몇번을 호출하던지 해당 렌더링의 이벤트 핸들러에서의 number는 항상 0이므로 state를 1로 세 번 설정하게 됩니다.
🎈 다음 렌더링 전에 동일한 state 변수를 여러 번 업데이트하기
다음 렌더링 전에 동일한 state 변수를 여러 번 업데이트 하고 싶다면 이전 큐의 state를 기반으로 다음 state를 계산하는 함수를 전달하도록 할 수 있어요!!
- 단순히 state 값을 대체(변경)하는 것이 아니라 React에 state 값으로 무언가를 하라고 지시
import { useState } from 'react'; export default function Counter() { const [number, setNumber] = useState(0); return ( <> <h1>{number}</h1> <button onClick={() => { setNumber(n => n + 1); setNumber(n => n + 1); setNumber(n => n + 1); }}>+3</button> </> ) }n ⇒ n + 1 는 업데이터 함수로 이 함수를 state 설정자 함수에 전달 할 때 React는 아래와 같이 동작합니다.
- React는 이벤트 핸들러의 다른 코드가 모두 실행된 후 해당 함수가 처리되도록 큐에 넣는다.
- 다음 렌더링 중에 React는 큐를 순회하며 최종으로 업데이트된 state를 제공
🏃 React가 이벤트 핸들러를 수행하는 동안 작동하는 방식
setNumber(n => n + 1)→n ⇒ n + 1함수를 큐에 추가setNumber(n => n + 1)→n ⇒ n + 1함수를 큐에 추가setNumber(n => n + 1)→n ⇒ n + 1함수를 큐에 추가
렌더링 중에 useState를 호출하면 React는 큐를 순회 하고 첫 number의 값은 0이었으므로 첫 번째 업데이터 함수에 n의 인수로 0을 전달
- 이후 React는 이전 업데이터 함수의 반환값을 가져와 다음 업데이터 함수의 n으로 전달하는 식으로 반복
queued update n 반환 n => n + 1 0 0 + 1 = 1 n => n + 1 1 1 + 1 = 2 n => n + 1 2 2 + 1 = 3 💡 React는 3을 최종 결과로 저장한 후
useState에서 반환📖 업데이터 함수
- 이전 상태 값을 기반으로 새로운 상태 값을 계산하고 업데이트하는 함수
⚠️ 업데이터 함수는 렌더링 중에 실행되기 때문에 업데이터 함수는 순수해야 하며 결과만 반환 해야 함.
- 업데이터 함수 내부에서 state를 변경하거나 다른 사이드 이팩트를 실행하려 하면 안된다!! ❌
🖥️ 다른 예시
<button onClick={() => { setNumber(number + 5); setNumber(n => n + 1); }}> ------ 결과: 6queued update n 반환 5으로 수정 0 5 n => n + 1 5 5 + 1 = 6 React는 6을 최종 결과로 저장하고 useState에서 반환
⬅️ 업데이트 큐
- 리액트에서 상태 변경을 추적하고 관리하는 내부 자료구조
컴포넌트에서 상태 업데이트가 발생할 때마다 업데이트를 바로 적용하지 않고 업데이트 큐에 추가.
🧩 특징
- 각 상태 업데이트는 큐에 업데이트 객체 로 저장
- 업데이트 객체들은 연결 리스트 형태로 관리
- 각 업데이트 객체는
action(새 상태 값 또는 업데이터 함수),lane(우선순위)등의 정보를 포함합니다.
🖥️ 예시
import { useState } from 'react'; export default function Counter() { const [number, setNumber] = useState(0); return ( <> <h1>{number}</h1> <button onClick={() => { setNumber(number + 5); setNumber(n => n + 1); setNumber(10); }}>Increase</button> </> ) } --- 버튼 클릭 결과 10🏃 React 동작 과정
setNumber(number + 5)
setNumber(0 + 5)- 5로 바꾸기 를 큐에 추가
setNumber(n => n + 1)- 업데이터 함수
- React는 이 함수를 큐에 추가
setNumber(10)- 10으로 바꾸기 를 큐에 추가
렌더링하는 동안 React는 state 큐를 순회
queued update n 반환 5로 수정 0 5 n => n + 1 5 5 + 1 = 6 10으로 수정 6 10 순회한 후 React는 10를 최종 결과로 저장하고 useState에서 반환
💡 정리
1️⃣ React는 이벤트 핸들러가 실행을 마친 후 state 업데이트를 처리 - batching
2️⃣ 하나의 이벤트에서 일부 state를 여러 번 업데이트하려면 업데이터 함수를 사용할 수 있다.
- 실제 값은