todo를 React.memo로 한층 더 최적화 가능하다!?!?
그렇다 알고리즘의 memoization 개념을 차용한것이다.
사실 todo가 변경될때 , 변경된 todo만 선별적으로 랜더링하면 되는데 변경되지 않은, 아니 변경하지 않아도 되는 다른 todo까지 함께 랜더링 되어서 비효율적이다. 아래와 같이 말이다.
마지막 todo를 지우면 지워진 todo만 없어지면 되는데 위의 todo까지 모두 랜더링 된다.
그럼 memo를 적용해보자. 참고로 React.memo는 HOC이다. 즉, 랜더링 되는 컴포넌트를 감싸야한다.
정말 간단하다. 그냥 랜더링 되는 자식 컴포넌트에 memo를 입혀주면 된다.(React.pureComponent와 거의 비슷하다고 한다)
그럼 passed된 props가 변경되지 않으면 이미 memo에 저장되어있는 컴포넌트를 사용하는것이다.
// todo.js
import { memo } from 'react';
function Todo({ id, completed, task }) {
console.log('TODO RENDERING', task);
blah
blah
blah
}
export default memo(Todo);
그럼 아래와 같이 랜더링 된다.
이로써 한층 업그레이드 된 todo이다.
단, 불필요하게 리랜더링 된다는 확신이 있을때 사용해야한다. 왜냐면, 말그대로 컴퓨터 메모리에 저장하기 때문에 확신도 없이 여기저기 다 사용하면 성능저하나 의도치 않은 버그가 발생할 수 있기 때문이다.
아 그리고 함수형 컴포넌트안에서 Hook으로도 사용가능하다. 이때는 useMemo를 사용하면 된다.
memo
에서 두 번째로 넘어가는 인자가 있다?
일단 바로 코드를 보자.
export default memo(Todo); --> Todo로 넘어가는 prop이 바뀔때만 랜더링 됨
export default memo(Todo,(prevProps,nextProps)=>false); --> 항상 랜더링 됨
export default memo(Todo,(prevProps,nextProps)=>true); --> 항상 랜더링 안 됨
memo할 경우의 수를 좀더 제어할 수 있도록 하는 것 같다.
이전의 prop과 새로 넘어오는 prop을 비교해서 다를때만 랜더링하게끔하게 하는 것 같다.
<Component name="foo" hello="world" />
<Component name="bar" hello="world" />
const areEqual = (prevProps, nextProps) => {
if(prevProps.name !== nextProps.name) return false;
if(prevProps.hello !== nextProps.hello) return false;
return true;
}
요런식으로 쓸수 있을 것 같다. 그래서 props 객체를 비교하는 것은 의미가 없다. props객체안에 있는 property를 비교해야한다. 객체는 매번 ref가 바뀌기 때문이다.