React.momo()

리액트는 UI성능을 향상시키기 위해 React.memo()라는 고차 함수를 제공합니다. 이 함수는 렌더링 결과를 메모이징하므로 불필요한 리렌더링을 줄일 수 있습니다.

React의 상태

 export function StudyCounter({userId, studyDate}){
   return (
   	<div>
    	    <p>이름:{userId}</div>
	    <p>날짜:{studyDate}</p>
	</div>
   );
 }
 
 function StudyTable({userId, studyDate, studyTime}) {
    return (
    	<div>
      		<StudyCounter userId={userId} studyDate={studyDate}/>
      		<p>사용시간:{studyTime}</p>
        </div>  
    );
 }

리액트에서는 props를 통해 하위 컴포넌트에 데이터를 전달합니다. 컴포넌트들은 해당 값들이 변경될 때 마다 리랜더링되어 화면에 새롭게 표현되게 되죠. 리액트의 가장 기본적인 개념입니다.

위 코드는 학생아이디와 날짜, 공부시간을 입력받아 화면에 표시해주는 프로그램입니다. 공부를 열심히 하는 학생들이 이 프로그램을 이용하여 하루 순수 공부시간을 계속해서 기록하고 있다고 가정해봅시다.

물론 위의 상태에서도 프로그램은 문제없이 작동합니다. 그러나 성능개선의 여지가 남아있습니다.

상태의 변경주기

userId, studyDate, studyTime을 각각 확인해봅시다. 열심히 공부하는 학생들은 매일 같은 아이디로 로그인하여 그날의 날짜와 시간을 계속해서 프로그램에 입력합니다.

학생들은 자주 공부하기 때문에 userId는 매일매일 동일한 경우가 많으며, studyTime은 계속해서 변화합니다.

즉, 같은 props로 전달되고 있지만 상태의 특성에 따라 변동성이 다를 수 있습니다.

변동성이 큰 순서대로 나열해보면 다음과 같습니다

studyTime > studyDate > userId

그러나 위의 우리가 만들어놓은 코드로는 studyTime이 변경될 경우, userId, studyDate을 표시하는 컴포넌트 역시 리랜더링 되는 문제가 있습니다.

이렇게 자주 변하는 상태와 그렇지 않은 상태가 있을때 React.memo()를 이용한 성능 최적화가 가능합니다.

성능최적화

 function StudyCounter({userId, studyDate}){
   return (
   	<div>
    	    <p>이름:{userId}</div>
	    <p>날짜:{studyDate}</p>
	</div>
   );
 }
 
 export const MemoStudyCounter = React.memo(StudyCounter);
 
 function StudyTable({userId, studyDate, studyTime}) {
    return (
    	<div>
      	    <MemoStudyCounter userId={userId} studyDate={studyDate}/>
      	    <p>사용시간:{studyTime}</p>
        </div>  
    );
 }

React.memo()는 리랜더링 상황에서 같은 props일 경우 메모이징 된 내용을 그대로 사용하게 되어있습니다. 이제 위 프로그램은 studyTime이 계속 변경된다고 하더라도, StudyCounter가상돔의 달라진 부분을 확인하지 않아, 성능상으로 이점이 나오게 됩니다.

React.memo()를 쓰는 상황

그렇다면 모든 컴포넌트를 메모이징하면 좋을까? 당연히 그렇지 않다.
props가 자주 바뀌는 컴포넌트를 메모이징하게 되면, 쓸때없는 연산과 더불어 메모리만 낭비하게 될 것이다.

즉, React.memo()는 같은 props로 랜더링이 자주 일어나는 컴포넌트에 쓰는 것이 적절하다. 특히, 해당 컴포넌트가 무거운 연산이 적용되고 있다면, 메모이징을 성능최적화가 큰 도움이 될 것이다.

profile
웹 개발을 공부하고 있는 윤석주입니다.

0개의 댓글