[BFE.dev] memo 2

치만·2026년 1월 18일

BFE.dev react

목록 보기
15/28
post-thumbnail

memo 2


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"

풀이 과정

1. 초기 렌더링

  • A 출력: root.render(<App/>)에 의해 App이 실행됩니다.
  • B 출력: A의 자식인 B를 호출합니다.

2. 상태 업데이트 후 재렌더링

  • A 출력: Aprops{ children: <B/> } 객체입니다. 매 렌더링마다 <B/>는 새로운 객체로 생성됩니다. App이 리렌더링될 때마다 A에게 전달되는 props의 참조값이 달라집니다.

    🤔 memo는 재렌더를 막지 못할까?

    JSX (<B />)는 실행 버튼이 아니라 '객체 생성'입니다.
    App 컴포넌트 함수가 재실행되면, 그 안에 적힌 <B /> 코드가 매번 읽힙니다.

    이때 React는 B를 즉시 실행하는 게 아니라, { type: B, props: {} }라는 단순한 자바스크립트 객체를 새로 만듭니다.이 객체는 매번 새로운 메모리 주소에 할당됩니다. 이것이 바로 설계도 객체입니다.

    memo는 이 객체가 생성되는 것 자체를 막을 권한이 없습니다. (이미 App 함수 내부에서 일어나기 때문입니다) memo는 '함수 본체'의 실행만 가로챕니다. memo는 "설계도 안에 적힌 props가 이전과 똑같은가?"를 검사합니다.

profile
🌱개발 기록장

0개의 댓글