번역 자료 / / 2025. 5. 26. 17:59

[react 번역] memo

출처: https://react.dev/reference/react/memo


개요

memo는 컴포넌트의 props가 바뀌지 않으면 리렌더를 건너뛰도록 해주는 React의 성능 최적화 API입니다. 부모가 리렌더되어도 props가 동일하다면 자식 컴포넌트의 리렌더를 방지할 수 있습니다. 단, memoization은 최적화일 뿐, 리렌더를 100% 막는 보장은 아닙니다.

const MemoizedComponent = memo(SomeComponent, arePropsEqual?);

Reference

memo(Component, arePropsEqual?)

컴포넌트를 memo로 감싸면, memoized 버전의 컴포넌트가 반환됩니다. 부모가 리렌더되어도 props가 바뀌지 않으면 자식 컴포넌트는 리렌더되지 않습니다.

  • 파라미터
    • Component: 메모이즈할 컴포넌트(함수형, forwardRef 등 모두 가능). 원본 컴포넌트는 수정되지 않고, 새 memoized 컴포넌트가 반환됩니다.
    • arePropsEqual? (optional): 이전 props와 새 props를 받아 true(동일) 또는 false(다름)를 반환하는 비교 함수. 기본적으로 Object.is로 얕은 비교(shallow equality)를 합니다. 대부분의 경우 생략해도 됩니다.
  • 반환값
    • memoized 컴포넌트(React 컴포넌트 타입). 원본과 동일하게 동작하지만, props가 바뀌지 않으면 리렌더를 건너뜁니다.

사용법

props가 바뀌지 않을 때 리렌더 건너뛰기

import { memo } from 'react';

const Greeting = memo(function Greeting({ name }) {
  return <h1>Hello, {name}!</h1>;
});

export default Greeting;
  • 부모가 리렌더되어도 name이 바뀌지 않으면 Greeting은 리렌더되지 않습니다.
  • props, state, context가 모두 동일하면 항상 같은 결과를 반환해야 합니다(순수 렌더링).

memoized 컴포넌트의 state/context 변화

  • memoized 컴포넌트도 자신의 state가 바뀌거나, 내부에서 사용하는 context 값이 바뀌면 리렌더됩니다. memo는 부모로부터 전달받는 props에만 영향을 미칩니다.

props가 객체/배열/함수일 때

  • memo는 props를 얕은 비교(Object.is)로 판단합니다. 매번 새로 생성되는 객체/배열/함수는 값이 같아도 참조가 달라서 리렌더가 발생합니다.
  • useMemo/useCallback으로 props를 메모이즈하거나, props를 최대한 단순하게(원시값 위주) 전달하세요.
function Page() {
  const [name, setName] = useState('Taylor');
  const [age, setAge] = useState(42);
  const person = useMemo(() => ({ name, age }), [name, age]);
  return <Profile person={person} />;
}

const Profile = memo(function Profile({ person }) {
  // ...
});
  • 더 좋은 방법은 props를 객체로 묶지 않고 개별 값으로 전달하는 것입니다.

커스텀 비교 함수 사용

  • props 구조가 복잡하거나, 얕은 비교로 충분하지 않을 때 두 번째 인자로 비교 함수를 전달할 수 있습니다.
const Chart = memo(function Chart({ dataPoints }) {
  // ...
}, arePropsEqual);

function arePropsEqual(prev, next) {
  return (
    prev.dataPoints.length === next.dataPoints.length &&
    prev.dataPoints.every((oldPoint, i) => {
      const newPoint = next.dataPoints[i];
      return oldPoint.x === newPoint.x && oldPoint.y === newPoint.y;
    })
  );
}
  • 비교 함수는 모든 props(함수 포함)를 반드시 비교해야 하며, deep equality는 성능에 주의해야 합니다.

트러블슈팅

객체/배열/함수 props로 인해 리렌더가 발생하는 경우

  • 부모에서 매번 새 객체/배열/함수를 생성해 props로 넘기면, memo가 있어도 리렌더가 발생합니다. useMemo/useCallback으로 참조를 고정하거나, props를 단순화하세요.

memo를 남용해도 괜찮은가?

  • memo는 성능 최적화일 뿐, 코드가 동작하지 않는 문제를 해결하는 용도로 쓰면 안 됩니다. 실제로 렌더링 비용이 크고, props가 자주 바뀌지 않는 컴포넌트에만 적용하세요.
  • memo를 남용하면 코드 가독성이 떨어질 수 있습니다.

참고 및 주의사항

  • memo는 props가 바뀌지 않을 때만 리렌더를 건너뜁니다. state/context 변화에는 영향을 주지 않습니다.
  • 비교 함수는 모든 props(특히 함수형 props)까지 정확히 비교해야 하며, deep equality는 성능에 주의하세요.
  • memoization은 최적화일 뿐, 리렌더를 100% 막는 보장은 아닙니다.

출처: https://react.dev/reference/react/memo

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유