
import * as React from 'react'
import { memo, useState } from 'react'
import { createRoot } from 'react-dom/client'
import { screen, fireEvent } from "@testing-library/dom";
function _B() {
console.log('B')
return null
}
const B = memo(_B)
function _A({ children }) {
console.log('A')
return children
}
const A = memo(_A)
function App() {
const [count, setCount] = useState(0)
return <div>
<button onClick={
() => setCount(count => count + 1)
}>
click me
</button>
<A><B/></A>
</div>
}
const root = createRoot(document.getElementById("root"));
root.render(<App />);
(async function () {
const action = await screen.findByText('click me')
fireEvent.click(action);
})()
"A"
"B"
"A"
A 출력: root.render(<App/>)에 의해 App이 실행됩니다.B 출력: A의 자식인 B를 호출합니다.A 출력: A의 props는 { children: <B/> } 객체입니다. 매 렌더링마다 <B/>는 새로운 객체로 생성됩니다. App이 리렌더링될 때마다 A에게 전달되는 props의 참조값이 달라집니다.🤔 왜
memo는 재렌더를 막지 못할까?
JSX (<B />)는 실행 버튼이 아니라 '객체 생성'입니다.
App컴포넌트 함수가 재실행되면, 그 안에 적힌<B />코드가 매번 읽힙니다.이때 React는
B를 즉시 실행하는 게 아니라,{ type: B, props: {} }라는 단순한 자바스크립트 객체를 새로 만듭니다.이 객체는 매번 새로운 메모리 주소에 할당됩니다. 이것이 바로 설계도 객체입니다.
memo는 이 객체가 생성되는 것 자체를 막을 권한이 없습니다. (이미 App 함수 내부에서 일어나기 때문입니다)memo는 '함수 본체'의 실행만 가로챕니다.memo는 "설계도 안에 적힌props가 이전과 똑같은가?"를 검사합니다.