1차 공부/공부한 자료

221226 useMemo

공대탈출 2022. 12. 26. 11:32
import { useMemo } from 'react'

 

function Component() {
    const value = calculate();
    return <div>{value}</div> 
}

function calculate() {
    return 10;
}

함수형 컴포넌트는 렌더링 >> 컴포넌트 함수 호출 >> 모든 내부 변수 초기화의 순서를 거칩니다.

컴포넌트가 렌더링 될 때마다 value라는 변수가 초기화되고, calculate함수는 반복적으로 호출됩니다.

만약 calculate함수가 무거운 일을 하는 함수라면 성능적으로 굉장히 비효율 적일 겁니다.

 

useMemo를 사용하면 렌더링 >> 컴포넌트 함수 호출 >> Memoize된 함수를 재사용 의 순서를 거칩니다.

useMemo를 사용해서 memoization을 해주면 calculate함수를 반복적으로 실행할 필요가 없습니다.

useMemo는 처음에 계산된 결과값을 메모리에 저장해서 컴포넌트가 반복적으로 렌더링이 되어도 계속 calculate를 재호출 하지 않고ㅡ 이전에 이미 계산된 결과 값을 메모리에서 꺼내와서 재사용할 수 있게 해줍니다.

 

useMemo는 첫 인자로 콜백함수, 두번쨰 인자로 의존성 배열을 받습니다.

의존성 배열의 값이 변경될 때만 콜백함수를 다시 호출해서 memoization된 값을 업데이트해준 후 다시 memoization해줍니다.

만약에 빈 배열을 넘겨주면 컴포넌트가 처음 마운트 되었을 때만 값을 계산해 memoization해주고 이후로는 진행하지 않습니다.

// 첫 번째 인자 콜백함수 
// 두 번째 인자 의존성배열
const value = useMemo(() => {
    return calculate();
},[item])

 

 

값을 재활용 하기위해 따로 메모리를 소비해서 저장해 놓기 때문에 불필요한 값을 모두 memoization해버리면 성능이 안좋아 질 수 있어 필요할 때만 사용해야합니다.

 

 

예제

객체는 참조형 데이터여서 원시형 데이터와 다르게 값이 저장될 때 주소값으로 저장이 됩니다. 즉 메모리상의 주소가 다르게 저장되어있는 것입니다.

const location = {country : isKorea ? '한국' : '일본'}
눈으로 보기에는 똑같지만 저장된 메모리 상의 주소가 완전히 다르기 때문에 useEffect의 location은 변경이 되었다고 생각할 수 있습니다.

const location = { country: isKorea ? '한국' : '일본' };

useEffect(() => {
    console.log('useEffect... 호출');
}, [location])

 

따라서 이것을 해결해주려면 useMemo를 아래와 같이 사용해서 memoization해주면 됩니다.

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

function App() {
  const [number, setNumber] = useState(0);
  const [isKorea, setIsKorea] = useState(true);
  
  // const location = { country: isKorea ? '한국' : '일본' };
  const location = useMemo(() => {
    return {
      country: isKorea ? '한국' : '일본'
    }
  }, [isKorea])

  useEffect(() => {
    console.log('useEffect... 호출');
    // 뭔가 오래 걸리는 작업
  }, [location])

  return (
    <header className="App-header">
        <h2>하루에 몇 끼 먹어요?</h2>
        <input type="number" value={number} onChange={(e) => setNumber(e.target.value)}/>
        <hr/>

        <h2>어느 나라에 있어요?</h2>
        <p>나라: {location.country}</p>
        <button onClick={() => setIsKorea(!isKorea)}>Update</button>
    </header>
  );
}

export default App;

'1차 공부 > 공부한 자료' 카테고리의 다른 글

typescript 공부 2  (0) 2023.01.02
typescript 공부1  (0) 2023.01.02
221224 socket.io / emit  (0) 2022.12.24
221224 웹소켓  (0) 2022.12.24
221224 HTTP통신  (0) 2022.12.24