[BFE.dev] useState()

치만·2026년 1월 27일

BFE.dev react

목록 보기
21/28
post-thumbnail

useState()


import * as React from "react";
import { useState } from "react";
import { createRoot } from "react-dom/client";
import { screen, fireEvent } from "@testing-library/dom";

function A() {
  console.log('render A')
  return null
}

function App() {
  const [_state, setState] = useState(false)
  console.log('render App')
  return <div>
    <button onClick={() => {
      console.log('click')
      setState(true)
    }}>click me</button>
    <A />
  </div>
}

const root = createRoot(document.getElementById("root"));
root.render(<App />);

(async function () {
  const action = await screen.findByText("click me");
  fireEvent.click(action);
  await wait(100);
  fireEvent.click(action);
  await wait(100);
  fireEvent.click(action);
})();

function wait(duration = 100) {
  return new Promise((resolve) => setTimeout(resolve, duration));
}



    

출력 결과

"render App"
"render A"
"click"
"render App"
"render A"
"click"
"render App"
"click"

풀이 과정

1. 초기 렌더링

  • render App/ render A 출력: 앱이 처음 구동되면서 모든 컴포넌트를 호출하면서 console.log를 출력합니다.

2. 첫 번째 클릭 후 상태 업데이트

  • click 출력: 버튼 핸들러가 실행됩니다.

  • render App / render A 출력: 상태값이 변경되었으므로 부모와 자식 컴포넌트 모두 재렌더링됩니다.

3. 두 번째 클릭

  • click 출력: 버튼 핸들러가 실행됩니다.

  • render App 출력: React는 render()의 출력값이 변경되지 않을 것이라고 예측할 수 없기 때문에 다시 render()를 호출하고 이전 render() 결과와 비교해야 하기 때문에 다시 App을 렌더링 시킵니다.

  • A 미출력: 확인 결과 결과가 이전과 같으므로 자식 컴포넌트까지 내려가지 않고 렌더링을 중단합니다.

💡 값이 변경된 후 동일한 값으로 업데이트될 때만 렌더링을 추가적인 리렌딩이 발생합니다.


4. 세 번째 클릭

  • click 출력: 버튼 핸들러가 실행됩니다.

  • 아무것도 출력되지 않음: 이미 앞선 단계에서 상태가 변하지 않는다는 것을 확신했기 때문에 이제 컴포넌트 함수를 호출하지 않습니다. (Bail out)

profile
🌱개발 기록장

0개의 댓글