TIL

Jony·2024년 6월 1일
0

[TIL]

목록 보기
34/46
post-thumbnail

memoization


  • 리렌더링의 조건

: 컴포넌트에서 state가 변경됐을 때

: 컴포넌트가 내려받은 props가 변경됐을 때

: 부모 컴포넌트가 되어 자식 컴포넌트 모두 됐을 리렌더링 됐을 때

  • 불필요한 렌더링이 발생하지 안도록 최적화를 해줘야 한다.

1. memo(React.memo) - 컴포넌트 캐싱

2. useCallback - 함수 캐싱

3. useMemo - 값을 캐싱


1. memo(React.memo)

:리렌더링의 발생 조건 중, 부모 컴포넌트가 리렌더링되면 자식 컴포넌트는 모두 리렌더링이 된다.


1번이 리렌더링 되면 2~7번 모두 리렌더링 된다.
4번이 리렌더링 되면 6,7번 모두 리렌더링 된다.

변경 사항 없는 컴포넌트가 때 리렌더링을 건너뛰는 것이 React.memo 도구다.


2. useCallback

: 인자로 들어오는 함수 자체를 메모이제이션한다.
: 두개의 인자를 받는다
( 첫 번째 인자 - 메모이제이션 해 줄 콜백함수
두 번째 인자 - 의존선 배열 )

예>

const calculate = useCallback((num) => {
    return num + 1;
}, [item])
  1. calculate 함수를 useCallback으로 감싸준다.
  2. calculate 함수는 메모이제이션된 함수를 가지고 있게된다.
  3. 의존성 배열 내부에 있는 값이 변경되지 않는 이상 다시 초기화 되지 않는다.
  4. 만약 의존성 배열 내부 값이 변경되면, calculate함수는 새로 만들어진 함수 객체로 초기화 된다.

3. useMemo

: 동일한 값을 리턴하는 함수를 반복적으로 호출할 경우, 처음 값을 메모리에 저장, 필요 시 메모리에서 꺼내 재사용 한다.
: 즉, 저장한 어떤 값이 필요할 때마다 캐시에서 꺼내 사용하는 것이다

  • 사용방법
// as-is
const value = 반환할_함수();

// to-be
const value = useMemo(()=> {
	return 반환할_함수()
}, [dependencyArray]);

dependencyArray값이 변경 될 때만 반환할_함수()가 호출된다.]
그 외엔 메모이제이션 해놨던 값을 가져오면 된다.



예시>

import React, { useEffect, useState } from "react";

function ObjectComponent() {
  const [isAlive, setIsAlive] = useState(true);
  const [uselessCount, setUselessCount] = useState(0);

  const me = {
    name: "Ted Chang",
    age: 21,
    isAlive: isAlive ? "생존" : "사망",
  };

  useEffect(() => {
    console.log("생존여부가 바뀔 때만 호출해주세요!");
  }, [me]);

  return (
    <>
      <div>
        내 이름은 {me.name}이구, 나이는 {me.age}!
      </div>
      <br />
      <div>
        <button
          onClick={() => {
            setIsAlive(!isAlive);
          }}
        >
          누르면 살았다가 죽었다가 해요
        </button>
        <br />
        생존여부 : {me.isAlive}
      </div>
      <hr />
      필요없는 숫자 영역이에요!
      <br />
      {uselessCount}
      <br />
      <button
        onClick={() => {
          setUselessCount(uselessCount + 1);
        }}
      >
        누르면 숫자가 올라가요
      </button>
    </>
  );
}

export default ObjectComponent;

useEffect 훅을 사용해 me의 정보가 바뀔때만 실행되게 dependency array를 넣었지만 애석하게도 count증가button을 클릭하면 계속해서 console.log가 찍힌다.

이유에 대해선 불변성과 관련이 있다.
버튼이 선택되어 uselessCount state가 변경되면
1. 리렌더링
2. 컴포넌트 함수 호출
3. me객체 재할당
4. useEffect의 dependency array에 의해 me객체가 변경됐는지 확인한다.
5. 그러나 React의 입장에선 me객체가 변경됐다고 인식하고 useEffect 내부 로직이 호출되기에 console.log에 표시된 것이다.

const me = useMemo(() => {
  return {
    name: "Ted Chang",
    age: 21,
    isAlive: isAlive ? "생존" : "사망",
  };
}, [isAlive]);

useMemo()를 써주면 uselessCount가 증가하더라도 영향을 받지 않게된다.

  • 주의사항 : useMemo의 사용 빈도수가 많게되면 별도의 메모리 확보가 과하게 되어 성능이 악화될 수 있으니 필요한 상황에만 사용하면 좋을 듯 싶다.
profile
알면 알수록 모르는 코태계

0개의 댓글