[아티클럽] React.memo() 현명하게 사용하기를 읽고
2021년 05월 10일, 21:30
React.memo
- React.memo는 고차 컴포넌트
- 컴포넌트가 동일한 props로 동일한 결과를 렌더링한다면, 마지막으로 렌더링된 결과를 재사용하게 함
- 얕은 비교만을 수행(다른 비교 동작을 원한다면 두 번째 인자로 별도의 비교함수 필요.)
React는 먼저 컴포넌트를 렌더링 한 뒤, 이전 렌더된 결과와 비교하여 DOM업데이트를 결정한다. 만약 렌더 결과가 다르다면 DOM에 업데이트 한다.
하지만, 컴포넌트를 렌더링 하는 비용도 크다면, 이를 메모이징해서 사용할 수 있다.
function Movie({ title, releaseDate }) {
return (
<div>
<div>Movie Title : {title}</div>
<div>Release Date : {releaseDate}</div>
</div>
);
}
export default React.memo(Movie);
// 얕은 비교만 수행하기 때문에 비교 방식을 수정하고 싶으면 두 번째 인자로 compare 함수를 전달하면 된다.
// function compareProps(prev, next) {
// return prev.title === next.title && prev.releaseDate === next.releaseDate;
// }
// export default React.memo(Movie, compareProps);
위의 코드에서 Props가 바뀌지 않는다면 Movie 컴포넌트는 React.memo를 사용했으니 이전 렌더링 때 메모이징 된 결과를 그대로 사용한다. 메모이징 한 결과를 재사용 함으로써, React에서 리렌더링 할 때 가상 DOM에서 달라진 부분을 확인하지 않아 성능상 이점을 누릴 수 있다.
- 클래스 컴포넌트의 경우 PureComponent 혹은 shouldComponentUpdate를 사용해야 하지만, PureComponent를 사용하라고 권장한다.(https://ko.reactjs.org/docs/react-component.html#shouldcomponentupdate)
언제 사용하면 좋을까?
-
같은 props로 렌더링이 자주 일어나는 컴포넌트
function MovieViewsRealtime({ title, releaseDate, views }) { return ( <div> <Movie title={title} releaseDate={releaseDate} /> Movie Views : {views} </div> ); } export default MovieViewsRealtime
views가 실시간으로 바뀐다고 생각해보자, 이러한 경우 title과 releaseDate는 바뀌지 않지만, views는 계속 바뀌기 때문에
메모이징을 하지 않으면 Movie 컴포넌트를 다시 실행하고 가상돔의 내용과 비교할 것이다.
하지만, React.memo를 활용하게 되면 이전 결과를 사용해 성능의 이점을 얻을 수 있을 것이다.
사용하지 말아야 하는 경우
- props가 자주 바뀌는 경우는 props에 대한 얕은 비교가 추가되는 상황이 되기 때문에 불필요한 연산을 더 하게 된다.
추가
-
만약 props가 함수인 경우?
- props가 함수인 경우에는 동일 instance여야 비교를 할 수 있으므로, useCallback을 이용해서 인스턴스를 동일하게 유지시켜야한다.
-
성능 개선의 용도로 써야한다.
-
렌더링을
방지
하기 위해서 사용하지 말아야한다(공식문서에 그렇게 나옴)
-
참고
출처: Toast UI, React.memo() 현명하게 사용하기
원문: https://dmitripavlutin.com/use-react-memo-wisely