본문 바로가기

크래프톤 정글/WIL

정글[Week_05]: React의 Component · State · Hooks 이해하기

지난 주에는 React가 가상 돔을 사용하여 어떻게 렌더링 비용을 획기적으로 절약하는지 알아보았다. 이번에는 렌더링 자체에만 국한하지 않고, React에서 각 요소들이 어떻게 운영되는지 알아보고자 한다.

 

React에서 중요한 개념, State

이전 글에서 React는 부분적인 렌더링을 하도록 최적화를 하였다고 기술하였다. 이때 부분적 랜더링을 화면을 직접 그리는 paint(페인팅)을 React가 부분화 하는 것으로 인식을 했었으나, 이는 렌더링 전체 과정에서 painting이 일부분이라는 사실을 간과한 오해였다. 페인팅은 정확히 말하자면 실제 돔(Real Dom)을 바탕으로 하여 브라우저가 수행하는 작업이다. 따라서, 만약 실제 돔이 부분적으로만 변경이 된다면, 브라우저 또한 부분적으로 페인팅.. 즉 자체적으로 페인팅 연산을 최적화하는 기능을 가지고 있다. 이를 보통 Damage Region이라고 한다.

React가 렌더링 비용을 획기적으로 줄이는 부분은, 가상 돔을 통해 실제 돔의 재구성 하는 비용을 최소화 하는 부분이다. 돔 자체도 무겁기 때문에, 가상 돔(Virtual Dom)이라는 판본을 만들어 연산을 최소화 하는 과정을 거친다.

 

그럼 State은 여기서 어떤 역할을 하는가?

처음에는 state라는 단어 의미를 기반으로 의미를 유추했었다. 말 그래도 상태를 관리하는 어떠한 기능일 거라고.. 엄밀히 말하자면, state은 가상 돔을 생성하는 트리거이다. 전체적인 흐름은 state 변경 → 가상 돔 재구성 → Diffing(비교) → 실제 돔 최소 반영 → 브라우저의 최소 페인팅으로 볼 수 있다고 한다. 

state을 사용하는 이유는 React는 파일 내 코드의 변화를 일일이 인지하지 않기 때문이다. 정확히는 일반 변수의 변화를 추적(Tracking)하지 않는다. 따라서, 특정 변수의 변화는 화면을 다시 그려할 신호로 인식해줘야 하기 때문에, state을 사용하게 된다. 예를 들어..

let generalVariable = 0;

  const [stateVariable, setStateVariable] = useState(0);
  
  const increaseGeneral = () => {
    generalVariable += 1;
  };

  const increaseState = () => {
    setStateVariable(stateVariable + 1);
  };

generalVariable(일반변수)와 stateVariable(state 변수)가 있다. 각각 함수를 사용해서 변수를 1씩 올릴 수 있다. 그러나 렌더링이 게시 되어 화면이 그려졌을 때 바뀌는 숫자는 state 변수이다.

 

State변수는 컴포넌트와 결합되어 있다

컴포넌트와 스테이

컴포넌트란 무엇인가, 한국어로 구성요소라고 번역하여 생각하였지만, 정의가 확 와 닽지 않았다. 컴포넌트는 HTML을 담은 Javascript 객체 형태이다. 코드로 예시를 표현하면 다음과 같다:

function Welcome() {
  return (
    <div className="container">
      <h1>이곳은 HTML 입니다.</h1>
    </div>
  );
}

HTML은 화면에 실제로 뿌려지도록 하는 DOM 설계 언어이다. 이것을 Javascript로 하나하나 블럭(요소)로 감싸, 로직에 따라서 불러오고 수정할 수 있도록 만든 것이다. 이러한 컴포넌트가 State와 결합되어 있는 이유는, 특정 state 값이 변경될 때 특정 컴포넌트에게 이를 변경하도록 요청하려는 이유이다. "이 값이 변하면 이 컴포넌트를 다시 그려라"라는 일종의 로직이라고 생각하면 좋겠다.

 

 

Hooker 함수들

다음으로는 hooker 함수가 있다. 이 함수들이 hook(갈고리)라는 이름이 붙은 이유는, 마치 갈고리 처럼 컴포넌트의 외부의 기능을 끌어다가 컴포넌트에 적용시키기 때문이라고 한다. 순서를 묘사하면 다음과 같다:

1. setCount(prev => prev + 1 ) 라는 수정 함수가 호출된다.
2. 해당 컴포넌트의 업데이트 큐(Queue)에는 상태 1 증가 라는 지시사항을 저장한다.
3. 함수 내부에서 const [count, setCount] = ustState(0) 코드를 감지한다.
4. useState라는 후커 함수가 실행 → Hooks인덱스 배열 → 큐의 지시사항을 갈고리 처럼 가져온다.
5. 지시사항에 따라 새로운 count를 계산한 다음, 컴포넌트에 돌려준다.

이후로는 렌더링 작업이 진행되고, 이는 이전 주에 배운 과정과 같다고 한다.