[React]최적화 - useMemo()

Hyoyoung Kim·2022년 8월 21일
0

React TIL

목록 보기
31/40

최적화 1 - 연산 결과 재사용

Memoization(최적화)

✔ 이미 계산 해본 연산결과를 기억해 두었다가 동일한 계산을 시키면 다시 연산하지 않고 기억해 두었던 데이터를 반환 시키게 하는 방법
연산 과정을 최적화한다

❌ Memoization 미적용

먼저 Memoization을 사용하지 않은 상황에서 일기의 감정점수의 통계치를 구하는 함수를 만들어 준다.

getDiaryAnalysis()함수 생성

지금 현재 data state가 가지고 있는 일기들 중에서
1. 기분이 좋은 일기(3,4,5)는 몇개 있는지
2. 기분이 안 좋은 일기(1,2)는 몇개 있는지
3. 기분이 좋은 일기의 비율은 어떻게 되는지
위의 세가지를 구하는 함수

//App컴포넌트

const getDiaryAnalysis = () => {
  console.log("일기 분석 시작");

  //1. 기분이 좋은 일기는 몇개 있는지를 구하는 함수
  //현재 일기 데이터 중에서 filter메서드를 이용하여 일기의 감정이 3이상인
  //것들을 새로운 배열에 넣어 그 배열의 길이를 goodCount상수에 넣어준다.
  const goodCount = data.filter((it)=> it.emotion >=3).length;

  // 2. 기분이 나쁜 일기의 개수를 구하는 함수
  // 현재 전체 일기의 개수에서 기분이 좋은 일기의 갯수를 빼주면 된다.
  const badCount = data.length - goodCount;

  //3. 좋은 일기의 비율을 구하는 함수
  const goodRatio = (goodCount/ data.length) *100;

  //위의 세개의 데이터를 객체로 리턴해줌
  return{goodCount, badCount, goodRatio};

}

//비구조화 할당으로 getDiaryAnalysis함수를 호출
const {goodCount, badCount, goodRatio} = getDiaryAnalysis();

  return (
    <div className="App">
      <DiaryEditor onCreate = {onCreate}/>
      <div>전체일기 : {data.length}</div>  
      <div>기분 좋은 일기 개수 : {goodCount}</div>  
      <div>기분 나쁜 일기 개수 : {badCount}</div>  
      <div>기분 좋은 일기 비율 : {goodRatio}</div>  
      <DiaryList onEdit={onEdit} onRemove={onRemove} diaryList ={data}/>
    </div>
  );
}

결과값

✔ 위의 결과값을 보면 Memoization을 사용하지 않은 상황은 App.js가 리렌더링 될때마다, getDiaryAnalysis()함수가 변화하지 않았음에도 리렌더링 된다.
✔ 굉장히 비효율적이다.

⭕ Memoization 적용

✔ 위와 같은 비효율성 막기위해 최적화를 위해 Memoization을 사용한다.
✔ Memoization를 적용하려면 useMemo함수를 사용해야 한다.

useMemo(콜백함수, []);

  1. 최적화를 위해 useMemo를 사용하면 된다.
  2. react에서 useMemo를 import해온다.
import { useEffect, useMemo, useRef,  useState} from 'react';
  1. useMemo는 최적화하고 싶은 함수를 감싸준다.
  2. useMemo함수는 첫번째 인자콜백함수를 받아서 콜백함수가 리턴하는 값(연산)을 최적화할 수 있게 도와준다.
  3. useMemo의 두번째 인자배열을 전달해야 한다.
const getDiaryAnalysis = useMemo(() => {
  console.log("일기 분석 시작");

  const goodCount = data.filter((it)=> it.emotion >=3).length;
  const badCount = data.length - goodCount;
  const goodRatio = (goodCount/ data.length) *100;

  return{goodCount, badCount, goodRatio};

},[data.length ])

// const {goodCount, badCount, goodRatio} = getDiaryAnalysis();
const {goodCount, badCount, goodRatio} = getDiaryAnalysis;
//✔ 이전에는 함수로서 호출하여 객체를 반환하는 형태였다면,
//useMemo()을 이용하게 되면 useMemo()의 콜백함수의 return값을 변수
//(getDiaryAnalysis)에 할당하는 형태가 된다.
//✔ 그래서 useMemo를 사용하게 되면 getDiaryAnalysis는 
//더이상 함수가 아닌 값이 되게 된다.


  return (
    <div className="App">
      <DiaryEditor onCreate = {onCreate}/>
      <div>전체일기 : {data.length}</div>  
      <div>기분 좋은 일기 개수 : {goodCount}</div>  
      <div>기분 나쁜 일기 개수 : {badCount}</div>  
      <div>기분 좋은 일기 비율 : {goodRatio}</div>  
      <DiaryList onEdit={onEdit} onRemove={onRemove} diaryList ={data}/>
    </div>
  );
}

✔ []안에 있는 값이 변화를 하게 된다는 순간에만 getDiaryAnalysis의 값을 변경하고, 그 이외의 상황에서는 반환한 값을 기억해, App.js가 리렌더링 되어도, 리렌더링을 하지 않는다.
✔ data.length가 변화하지 않는 상황에서 App.js가 리렌더링 될때에는 getDiaryAnalysis의 useMemo의 콜백함수가 실행되지 않으며, data.length가 변화할때만, getDiaryAnalysis의 useMemo의 콜백함수가 호출된다.

0개의 댓글