memo는prop이 안 바뀌면, 컴포넌트의 리랜더링을 하지 않도록 한다.
const MemoizedComponent = memo(SomeComponent, arePropsEqual?)
memoize하고 싶은 컴포넌트. functions, forwardRef 컴포넌트도 가능하다.원래 리액트는 부모 컴포넌트가 리랜더링되면 자식 컴포넌트는 자동으로 리랜더링된다. 하지만
memo를 사용하면, 그props가 바뀌지 않은 한, 컴포넌트 리랜더링이 되지 않는다. 이걸 보고 그 컴포넌트가memoized되었다고 한다.
react의 모든 컴포넌트는 pure rendering logic을 따라야 한다. 이건 prop, state, context 가 변경되지 않는 한 같은 결과값을 반환해야 한다는 것이다. memo를 쓰면 정확히 이 기준을 따르고 있는 것이다.
아무리 컴포넌트가
memoized되었어도, 만약context나 상태값이 변경되면 리랜더링은 일어난다.
(정리) 결국 핵심은, React.memo의 사용은 "내부 상태 변경에 따른 리렌더링을 방지하는 것"이 아니라, "부모 컴포넌트로부터 받은 props가 변경되지 않았을 때 불필요한 리렌더링을 방지하는 것"이다.
props 끼리 얕은 비교를 했을 때, 다르면 re-render를 한다. 똑같으면, 내부값이 변경되어도 re-render를 안 한다.참조값을 비교하는 것이기 때문이다. react는 Object.is 를 사용하여 값을 비교한다. Object.is(3, 3) is true, but Object.is({}, {}) is false. 객체는 참조타입이기 때문에, 객체 리터럴은 별개의 두 개를 사용한다.memo를 사용하는 것의 효율을 높이고 싶으면, prop의 변화를 최대한 안 줘야 한다.const person = useMemo(
() => ({ name, age }),
[name, age]
);
const Profile = memo(function Profile({ person }) {
// ...
});
useMemo를 사용해서 name, age 가 변경되지 않을 때 person 객체를 계속 메모이제이션 할 수 있도록 처리하고, 그 person을 memo의 prop으로 줌으로써, person 객체가 새로 생성되지 않을 때는 memo 컴포넌트가 re-render되지 않게 한다.props 값을 비교한다. 그래서 내부의 값이 같다하더라도 그 객체 자체가 새로 만들어졌다면, 리액트는 다른 값으로 인식한다.