profile image

L o a d i n g . . .

연산 결과 값을 재사용하는 방법

 

 

Memoization 이해하기

 

Memoization?

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

ex) 시험을 볼 때, 이미 풀어본 문제는 다시 풀지 않아도 답을 알고 있는 것

 

 

 

 

 

 

 

 

감정을 기준으로 일기 분석 

  const getDiaryAnalysis = () => {
    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 }
  }

 

const { goodCount, badCount, goodRatio } = getDiaryAnalysis();

getDiaryAnalysis return이 객체 이므로

App return 전에 객체 비구조화를 통해 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>
  );

 

App 컴포넌트 리턴시 전체일기와 기분에따른 일기 개수, 비율을 표시하게 했다.

 

 

 

 

 

이제 이 getDiaryAnalysis 콘솔 출력 횟수를 확인해보자

 

 

일기 분석 시작이 2번 출력 된 것을 확인할 수 있다.

이유는 mount 될때 getDiaryAnalysis()를 한 번 출력하고 

getData에 API가 추가되고 setData가 되면서 데이터가 바뀌면서 Update(reRender)가 된다.

그 때 코드가 다시 수행되면서 getDiaryAnalysis()가 다시 호출된다.

 

함수형 컴포넌트도 함수이기 때문에 이 App 컴포넌트는 return하는 JSX 문법 html DOM요소들은 화면에 반영이 될 뿐 자바스크립트가 호출되는 것도 똑같다

 

리랜더링 === 앱함수가 한 번더 호출된다.

 

 

 

 

다만 지금은 감정점수 수정이아닌 content 를 수정해도 getDiaryAnalysis가 리랜더링 된다. (App 컴포넌트가 리랜더링 되기때문)

 

이때 연산 최적화를 위해 Memoization을 사용한다.

 

 

 

 

useMemo

import React, { useState, useRef, useEffect, useMemo } from 'react';

useMemo함수 안에 콜백함수를 받아서 콜백함수가 리턴하는 값을 연산하는데 최적화 시킨다.

두번째 인자로는 배열을 전달한다. 배열에 있는 인자가 변화할 때만 콜백함수를 Update한다.

 

 

 

  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;

useMemo를 사용하게되면 더이상 함수가 아닌 값이 된다.

그래서 getDiaryAnalysis를 ()함수기호를 지우고 값자체로 호출해준다.

 

 

 

이젠 콘텐츠 수정을 해도 getDiaryAnalysis 최적화 안에 포함되지 않는 연산이기 때문에

console을 호출하지 않는다.

 

 

 

참고 : 

- 한 입 크기로 잘라먹는 리액트

 

반응형
복사했습니다!