ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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>
    1. setNumber(number + 1)
      • number는 0, React는 다음 렌더링에서 number를 1로 변경할 준비
    2. setNumber(number + 1)
      • number는 0, React는 다음 렌더링에서 number를 1로 변경할 준비
    3. 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는 아래와 같이 동작합니다.

    1. React는 이벤트 핸들러의 다른 코드가 모두 실행된 후 해당 함수가 처리되도록 큐에 넣는다.
    2. 다음 렌더링 중에 React는 큐를 순회하며 최종으로 업데이트된 state를 제공

     

    🏃 React가 이벤트 핸들러를 수행하는 동안 작동하는 방식

    1. setNumber(n => n + 1) → n ⇒ n + 1 함수를 큐에 추가
    2. setNumber(n => n + 1) → n ⇒ n + 1 함수를 큐에 추가
    3. 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);
    }}>
    
    ------
    결과: 6

     

     

    queued 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 동작 과정

    1. setNumber(number + 5)
      • setNumber(0 + 5)
      • 5로 바꾸기 를 큐에 추가
    2. setNumber(n => n + 1)
      • 업데이터 함수
      • React는 이 함수를 큐에 추가
    3. 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를 여러 번 업데이트하려면 업데이터 함수를 사용할 수 있다.

     

    'FE > React' 카테고리의 다른 글

    UI 표현하기  (0) 2025.10.23
    React 개요  (0) 2025.10.23

    댓글

Designed by Tistory.