React.memo 설명

기본 개념

React는 부모 컴포넌트가 re-render되면 자식 컴포넌트도 무조건 re-render 한다.

예시)

ApplicationConfig (state 변경 → re-render)
├─ ConfigSelector ← props 안 바뀌어도 re-render
└─ ConfigurationDisplay ← props 안 바뀌어도 re-render

React.memo는 무조건 렌더링되는 것을 막는 래퍼. "이전 props랑 같으면 re-render 하지 마" 라고 알려준다.

// memo 없음: 부모가 re-render하면 무조건 같이 re-render (실질적으로 바뀌는 것이 없어도)
export const ConfigurationDisplay = (props) => { ... }; 

// memo 있음: props가 바뀔 때만 re-render
export const ConfigurationDisplay = React.memo((props) => { ... });

"props가 같다"는 어떻게 판단?

기본 동작은 shallow equality — 모든 prop을 ===로 비교합니다.

// Primitive: 문자열, 숫자, boolean — 값이 같으면 같다
'dev' === 'dev' // true → re-render 안 함
42 === 42 // true → re-render 안 함

// 객체, 배열, 함수 — 참조가 같아야 같다
{ a: 1 } === { a: 1 } // false! 서로 다른 객체 → re-render 함

그래서 부모에서 객체를 넘기면 memo가 아무런 소용없습니다. (매번 서로 다른 객체가 생성되므로)

// ❌ 매 렌더마다 새 객체/함수 생성 → memo 무력화

<ConfigurationDisplay
	configData={{ autoscaling: data }} // 매번 새 객체
	onToggle={() => toggle()} // 매번 새 함수
/>

// ✅ 참조를 안정시켜야 memo가 동작
const stableData = useMemo(() => ({ autoscaling: data }), [data]);
const stableToggle = useCallback(() => toggle(), [toggle]);
// UseCallback은 무슨 이유로 안정... memo을 메모하는건 좀 골떄리는군.
<ConfigurationDisplay
	configData={stableData}
	onToggle={stableToggle}
/>

커스텀 비교 함수

두 번째 인자로 "어떤 props를 비교할지" 직접 정할 수 있습니다:

React.memo(Component, (prevProps, nextProps) => {
	// true 반환 → "같다" → re-render 안 함
	// false 반환 → "다르다" → re-render 함
});

이번 작업에서 ConfigurationDisplay가 이걸 쓰고 있었는데, isAutoSyncLoading을 비교 대상에 안 넣어서 Spinner가 안 보이는 버그가 났죠.

그래서 언제 쓰나?

상황 판단
부모가 자주 re-render + 자식 렌더링이 무거움 memo 쓸만함
어드민 페이지, 단순 UI 필요 없음
props에 매번 새 객체/함수가 오는 구조 memo 써봤자 소용없음

핵심: React.memo는 최적화 도구이지 필수가 아닙니다. 성능 문제가 측정된 후에 적용해도 늦지 않고, 잘못 쓰면 오히려 버그를 만듭니다. 이번 작업에서 삭제한 이유가 정확히 그거예요.

참고

useMemo와 React.Memo는 다른 개념 아래는 Cursor(opus 4.6 의 설명)

React.PureComponent (클래스 시대, 2015)
  → "shouldComponentUpdate에서 shallow compare 자동화"
  → props/state가 같으면 리렌더 건너뜀

React.memo (함수형 전환, 2018 / React 16.6)
  → PureComponent의 함수형 컴포넌트 버전
  → props가 같으면 리렌더 건너뜀

useMemo (Hooks 도입, 2019 / React 16.8)
  → 컴포넌트 내부의 값 계산을 메모이즈
  → deps가 같으면 재계산 건너뜀
React.memo = 건물 출입구의 보안 게이트 
→ "이 사람 아까 온 사람이랑 같네? 다시 검사 안 해도 됨"
→ 컴포넌트 진입 자체를 막음

useMemo = 건물 안 사무실의 캐시 서랍
→ "이 계산 아까 한 거랑 같네? 서랍에서 꺼내 씀"
→ 컴포넌트 안에서 특정 계산만 건너뜀