
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"
render App/ render A 출력: 앱이 처음 구동되면서 모든 컴포넌트를 호출하면서 console.log를 출력합니다.click 출력: 버튼 핸들러가 실행됩니다.
render App / render A 출력: 상태값이 변경되었으므로 부모와 자식 컴포넌트 모두 재렌더링됩니다.
click 출력: 버튼 핸들러가 실행됩니다.
render App 출력: React는 render()의 출력값이 변경되지 않을 것이라고 예측할 수 없기 때문에 다시 render()를 호출하고 이전 render() 결과와 비교해야 하기 때문에 다시 App을 렌더링 시킵니다.
A 미출력: 확인 결과 결과가 이전과 같으므로 자식 컴포넌트까지 내려가지 않고 렌더링을 중단합니다.
click 출력: 버튼 핸들러가 실행됩니다.
아무것도 출력되지 않음: 이미 앞선 단계에서 상태가 변하지 않는다는 것을 확신했기 때문에 이제 컴포넌트 함수를 호출하지 않습니다. (Bail out)