모든 랜더링은 고유의 Prop과 State가 있다.

이펙트에 대해 이야기 하기 전에, 먼저 랜더링에 대해 이야기 해야한다.

여기 카운터 컴포넌트가 있다. 하이라이트된 줄을 자세히 봐보자

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );

이게 무슨 뜻일까? count가 어찌어찌 state의 변화를 관찰하여 자동으로 업데이트 한다는 걸까? 처음에 리액트를 배우면서 직관적으로 받아들일 때는 유용한 생각일 수 있지만, 정확한 멘탈 모델은 아니다.

이 예제에서 count는 그저 숫자이다. 마법의 "데이터바인딩" 이나 "워쳐" 나 "프록시", 혹은 비슷한 그어떤 것도 아니다. 그냥 아래와 같이 단순한 숫자에 불과하다.

const count = 42;
// ...
<p> You clicked {count} times </p>
// ...

처음으로 컴포넌트가 랜더링될 떄, useState로부터 가져온 count 변수는 0이다. setCount(1)을 호출하면, 다시 컴포넌트를 호출하고. 이때 count는 1이 되는 식이다.

// 처음 랜더링 시
function Counter() {
  const count = 0; // useState() 로부터 리턴
  // ...
  <p>You clicked {count} times</p>
  // ...
}

// 클릭하면 함수가 다시 호출된다
function Counter() {
  const count = 1; // useState() 로부터 리턴
  // ...
  <p>You clicked {count} times</p>
  // ...
}

// 또 한번 클릭하면, 다시 함수가 호출된다
function Counter() {
  const count = 2; // useState() 로부터 리턴
  // ...
  <p>You clicked {count} times</p>
  // ...
}

state를 업데이트 할때마다, 리액트는 컴포넌트를 호출한다. 매번 랜더 결과물은 고유의 counter 상태 값을 "살펴본다". 그리고 이 값은 함수 안에 상수로 존재하는 값이다.

따라서 위에 표시한 줄은 어떤 데이터 바인딩도 수행하지 않는다.

<p>Yout clicked {count} times</p>

이건 랜더링 결과물에 숫자값을 내장하는 것에 불과하다. 이 숫자 값은 리액트를 통해 제공된다. setCount를 호출할 때, 리액트는 다른 count 값과 함께 컴포넌트를 다시 호출한다. 그러면 리액트는 가장 쵯니의 랜더링 결과물과 일치 하도록 DOM을 업데이트 한다.

명심해야 할 점은 여느 특정 랜더링 시 그 안에 있는 count 상수는 시간이 지난다고 바뀌는 것이 아니라는 것이다. 컴포넌트가 다시 호출되고, 각각의 랜더링마다 격리된 고유의 count값을 보는 것이다.

모든 렌더링은 고유의 이벤트 핸들러를 가진다.

아래의 예제를 보자. 이 컴포넌트는 3초 뒤에 count 값과 함께 얼럿을 띄워준다.

function Counter() {
  const [count, setCount] = useState(0);

  function handleAlertClick() {
    setTimeout(() => {
      alert('You clicked on: ' + count);
    }, 3000);
  }
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
      <button onClick={handleAlertClick}>
        Show alert
      </button>
    </div>
  );
}

Click me 버튼을 눌러 카운터를 3으로 증가시킨 후, Show alert 버튼을 누르고 얼럿창이 뜨기 전에 카운터를 마구 증가시켜보자.

이럴때 얼럿에는 어떤 값이 나타날까 ? 얼럿이 등장할 시점의 count값이 나오게 될까? 아니면 Show alert 버튼을 클릭했을 시점의 값인 3이 나오게 될까 ?

나는 얼럿이 뜰 시점의 count가 나올거라고 예상을 했는데 아니었다. 버튼을 클릭했을 시점의 count 인 3이 출력되었다. 얼럿은 버튼을 클릭할 때의 state를 잡아두게 된다.