본문 바로가기
목차
[노트장] 적으며 정리해 보는 이론/리액트문서

[리액트문서보기][상호작용성 더하기] 스냅샷으로서의 State

by 졸린부엉이 2024. 3. 26.

 

학습내용

  • state 설정으로 리렌더링이 동작하는 방식
  • state 업데이트 시기 및 방법
  • state를 설정한 직후에 state가 업데이트되지 않는 이유
  • 이벤트 핸들러가 state의 “스냅샷”에 접근하는 방법

 


 

state를 설정하면 렌더링이 동작합니다.  

클릭과 같은 사용자 이벤트에 반응하여 사용자 인터페이스가 직접 변경된다고 생각할 수 있습니다. React에서는 이 멘탈 모델과는 조금 다르게 작동합니다. 이전 페이지에서 state를 설정하면 React에 리렌더링을 요청하는 것을 보았습니다. 즉, 인터페이스가 이벤트에 반응하려면 state를 업데이트해야 합니다.

 

import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 1);
      }}>+3</button>
    </>
  )
}


// 버튼을 클릭하면 다음과 같은 일이 발생합니다.
button onClick 이벤트 실행됩니다.
setNumber(0)가 number를 1로 설정하고 새로운 렌더링을 큐에 넣습니다.
[큐 ?? +참고]
React는 새로운 isSent값에 따라 컴포넌트를 다시 렌더링합니다.

 

[+참고]

작업 큐(Work Queue)는
작업을 일시적으로 저장하고 나중에 처리하기 위한 자료구조입니다. 일반적으로 FIFO(First-In-First-Out) 방식으로 작동하며, 먼저 추가된 작업이 먼저 처리됩니다.
React에서의 작업 큐는 상태(State)나 프로퍼티(Properties) 변경 등과 같은 이벤트가 발생할 때 해당 컴포넌트의 렌더링 작업을 일시적으로 저장하고, 나중에 실행될 수 있도록 큐에 추가합니다. 이 작업 큐는 React의 내부 메커니즘에서 상태 변화를 감지하고, 변경된 내용을 화면에 반영하기 위해 사용됩니다.
작업 큐는 비동기적인 방식으로 작동하며, 작업을 큐에 추가할 때마다 현재 실행 중인 작업이 완료된 이후에 순차적으로 처리됩니다. 따라서 React에서의 작업 큐는 상태 변화에 따라 컴포넌트를 다시 렌더링하는 작업을 보류하고, 적절한 시기에 이를 실행하여 화면을 업데이트합니다.

 

 

 


 

 

 

랜더링은 그 시점의 스냅샷을 찍습니다 

“렌더링”이란 React가 컴포넌트, 즉 함수를 호출한다는 뜻입니다. 해당 함수에서 반환하는 JSX는 시간상 UI의 스냅 샷과 같습니다. prop, 이벤트 핸들러, 로컬 변수는 모두 렌더링 당시의 state를 사용해 계산됩니다.

 

 

 

React가 컴포넌트를 다시 렌더링할 때.

  1. React가 함수를 다시 호출합니다.
  2. 함수가 새로운 JSX 스냅샷을 반환합니다.
  3. 그러면 React가 함수가 반환한 스냅샷과 일치하도록 화면을 업데이트합니다.

 

 

 

 

 

 

React에서 UI 업데이트 과정은 다음과 같이 설명할 수 있습니다:

렌더링: React는 컴포넌트를 호출하여 JSX를 생성합니다. JSX는 UI의 현재 상태를 나타내는 "스냅샷"이라고 볼 수 있습니다. 이때 컴포넌트 내부의 상태, 속성 등이 사용되어 UI가 어떻게 보일지가 결정됩니다.

가상 DOM 비교: 이전에 렌더링된 UI와 새로 생성된 UI(스냅샷)를 비교합니다. React는 이를 효율적으로 처리하기 위해 가상 DOM을 사용합니다. 이전에 렌더링된 가상 DOM과 새로 생성된 가상 DOM을 비교하여 변경된 부분을 찾습니다.

변경 감지: React는 이전 UI와 새로운 UI 사이의 차이를 감지합니다. 이를 통해 변경된 요소와 그에 따른 작업을 식별합니다. 예를 들어, 특정 요소의 텍스트가 변경되었거나 새로운 요소가 추가되었을 수 있습니다.

실제 DOM 업데이트: 변경된 부분만을 실제 DOM에 반영합니다. React는 이전 UI와 새로운 UI를 비교하여 변경된 요소에 대한 작업을 수행합니다. 이를 통해 필요한 DOM 조작만을 수행하여 성능을 최적화합니다. 변경된 부분을 화면에 반영함으로써 사용자에게 최신 정보를 제공합니다.

.

 

 

 

 

[+유의코드]

import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1> // 출력: 1: 1, 2: 2 , 3: 3
      <button onClick={() => {
         setNumber((prev) => prev + 1);
         
        setTimeout(() => {
          console.log(number) // 3초 뒤 출력: 0
        }, 3000);
        
        console.log(number) // 출력: 1: 0, 2: 1 , 3: 2
      }}>+1</button>
    </>
  )
}

 

state변경 값이 함수에서 즉시 반영이 안되는 이유는.

함수를 호출하여 상태를 업데이트하면, 새로운 값은 즉시 적용되지 않고, 현재 렌더링 사이클이 종료된 후에 다음 렌더링 사이클에서 반영됩니다. 이전 상태와 새로운 상태를 비교하려면 다음 렌더링 사이클에서 업데이트된 값을 사용하여 비교해야 합니다.

다음 렌더링 사이클이란, 현재 실행 중인 JavaScript 코드가 완료된 후 React가 다시 컴포넌트를 렌더링할 때를 의미합니다.

 

 

 

 


 

 

◼ 요약 

 

  • state를 설정하면 새 렌더링을 요청합니다.
  • React는 컴포넌트 외부에 마치 선반에 보관하듯 state를 저장합니다.
  • useState를 호출하면 React는 해당 렌더링에 대한 state의 스냅샷을 제공합니다.
  • 변수와 이벤트 핸들러는 다시 렌더링해도 “살아남지” 않습니다. 모든 렌더링에는 고유한 이벤트 핸들러가 있습니다.
  • 모든 렌더링(및 그 안의 함수)은 항상 React가 그 렌더링에 제공한 state의 스냅샷을 “보게” 됩니다.
  • 렌더링 된 JSX에 대해 생각하는 방식과 유사하게 이벤트 핸들러에서 state를 대체할 수 있습니다.
  • 과거에 생성된 이벤트 핸들러는 그것이 생성된 렌더링 시점의 state 값을 갖습니다.

 

 

 

 

 

 

 

[참고]

https://ko.react.dev/learn/state-as-a-snapshot

https://www.youtube.com/watch?v=gM3dCv_dSOk&list=PLjQV3hketAJkh6BEl0n4PDS_2fBd0cS9v&index=18