[React][최적화] React memo

jiseong·2021년 9월 28일
0

T I Learned

목록 보기
85/291
post-custom-banner

React memo의 효과!!

 <div css={searchForm} ref={refSearchForm}>
      <div name="location" css={searchFormCol} onClick={changePopupType}>
        <h5>위치</h5>
        <input
          onChange={e => handleChange(e.target.value)}
          name="location"
          type="text"
          autoComplete="off"
          placeholder="어디로 여행가세요?"
        />
      </div>
      <LocationPopup popupState={popupType === 'location'} />
      <div css={serachFormDivide}></div>
      <div name="calendar" css={searchFormCol} onClick={changePopupType}>
        <h5>체크인</h5>
        <p>날짜 입력</p>
      </div>
      <div css={serachFormDivide}></div>
      <div name="calendar" css={searchFormCol} onClick={changePopupType}>
        <h5>체크아웃</h5>
        <p>날짜 입력</p>
      </div>
      <CalendarPopup popupState={popupType === 'calendar'} />
      <div css={serachFormDivide}></div>
      <div name="guest" css={[searchFormCol, searchFormColLast]} onClick={changePopupType}>
        <div>
          <h5>인원</h5>
          <p>게스트 추가</p>
        </div>
        <Link to="/accommodationList">
          <button css={searchFormColLastBtn}>
            <SearchIcon />
          </button>
        </Link>
      </div>
      <GuestPopup popupState={popupType === 'guest'} />
</div>

위의 방식으로는 input태그에 값을 입력할때마다 많은 컴포넌트들이 리렌더링된다.
그 중에서도 Calendar 관련 컴포넌트에서 재계산과 불필요한 리렌더링이 일어나 랙이 발생되었다.

React Memo 사용하기

input에 값이 입력될 때 state가 변경되는데 이 때, 달력은 리렌더링이 될 필요가 없다.

이를 해결하기 위해서 아래 코드와 같이 React.Memo를 이용하여 동일한 값일 때는 다시 렌더링이 되지 않도록 방지해주었고 계산이 많이 쓰이는 함수에도 useMemo를 사용하여 불필요한 계산을 하지 않게 해주었다.

// CalendarContainer.js
const leftMonth = useMemo(() => getMonthData(leftDate), [moveMonth]);
const rightMonth = useMemo(() => getMonthData(nextDate), [moveMonth]);
// SingleCalendar.js
function SingleCalendar({ monthData }) {
  return (
    <div css={calendarWrap}>
      <strong css={title}>
        {monthData.year}{monthData.month}</strong>
      <div css={header}>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
      </div>

      <div css={dateWrap}>
        {monthData.arr.map((date, i) => {
          return (
            <div css={dateBtn({ date })} key={`${monthData.year} + ${i}`}>
              {date?.day}
            </div>
          );
        })}
      </div>
    </div>
  );
}

export default React.memo(SingleCalendar);

결과

그 결과, 눈에 띄게 효과를 볼 수 있었다.

그렇다면 모든 컴포넌트에 React Memo를 사용하면 좋지 않을까라는 생각이 들었다. 하지만 메모이제이션 경우를 체크하기 위한 불필요한 비용이 발생하기 때문에 정말로 필요한 컴포넌트에만 사용하는 것이 좋다고 한다.

추가적으로, React.memo 에서 두번째 파라미터의 propsAreEqual 이라는 함수를 사용해 특정 값들만 비교할수도 있다.

export default React.memo(
  SampleComponent,
  (prevProps, nextProps) => prevProps.users === nextProps.users
);
post-custom-banner

0개의 댓글