상태가 변화하는 과정을 DEEP하게 공부해보기
React에서 상태가 변경되면 다시 렌더링 해준다는 개념으로 useState를 사용해왔다. 하지만 사용중에 원하던 상태값이 아직 반영되지 않았거나 상태가 변경되어도 렌더링이 되지 않는 등의 문제를 접할 수 있었다.
상태 업데이트로 인해 React에서는 어떠한 과정이 일어나는지 조금 더 깊게 이해해보았다.
- 사용자가 버튼을 클릭 혹은 폼 입력을 하는 등의 이벤트가 발생
- 해당 이벤트에 대한 핸들러 함수가 실행된다.
- e.g 폼 제출에 대한
handleSubmit
함수가 있다.
- e.g 폼 제출에 대한
- 이벤트 핸들러 함수 내에서
useState
의 setter 함수(e.g:setText)가 호출 - 이 함수 호출로 인해 React는 상태 변경을
예약
- 실제로 상태는 바로 업데이트 되지 않고 예약(setter 함수가 스택에 쌓이는 개념과 비슷함)
- 상태 변경을
일괄적
으로 처리하기 위해서 예약을 한다.
- 상태 변경을
- 예약된 setter 함수들은 이벤트 루프가 완료될 때까지 대기
- 일괄 처리에서 대기 중인 setter 함수가 모두 처리
- setter 함수가
직접적인 상태 할당
인 경우 상태에 새로운 값을직접
제공 - setter 함수가
업데이터 함수
인 경우 이전 상태를 기반으로 새로운 상태를계산
- 이렇게 일괄 처리로 변경된 상태들이
최종 상태
가 결정 - 일괄 처리 덕분에 여러 상태값이 변경되어도 렌더링은 한번만 일어남
- React는 여러 상태 업데이트를 일괄 처리하는 방식을 사용하여 효율을 높인다.
- 아직
최종 상태
값이 반환된 것은 아니다.
- 일괄 처리에서의
최종상태
가 기존 상태와 동일하다면 리렌더링은 생략 - 상태가 변경되었다고 판단될 시 React는 컴포넌트를 리렌더링
- 이 과정에서 useState는 최신 상태를 반환하고 변수에 할당한다.
- 리렌더링이 일어나면 새로운 JSX 구조가 생성
- 리액트는 새로운 JSX 구조를 스냅샷으로 저장
- 이는 Virtual DOM의 형태로
메모리 상에
존재
- React는
이전 상태의 Virtual DOM
과새로운 Virtual DOM
을 비교하여 (Diffing 알고리즘), 실제 DOM에 반영할 변경 사항을 결정한다.- 즉, 변경이 필요한 DOM만이 업데이트 된다.
import React, { useState } from "react";
function MyComponent() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment</button>
<p>{count}</p>
</div>
);
}
- button을 클릭하면 이벤트가 실행 setCount로 상태 업데이트 예약
- 이벤트 루프가 종료되면 상태 업데이트 일괄처리
- count + 1 로 최종상태 결정
- 이전 상태값과 다르기에 리렌더링 실행
- count + 1 최종상태 값 반환
- 새로운 JSX 스냅샷 저장
- 이전 JSX 스냅샷과 새로운 JSX 스냅샷 비교
<p>
태그 내부의 텍스트가 변경되므로, 실제<p>
DOM 변경<button>
태그는 변경되지 않았으므로, 이 부분은 그대로 유지
- 이 과정을 통해 React는 효율적으로 UI를 업데이트하며, 개발자에게 선언적인 프로그래밍 방식을 가능하게 함.