ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React.js] Hooks - useCallback, useMemo
    Front-End(Web)/React - 프레임워크(React, Next) 2020. 12. 27. 17:37
    반응형

    기본 프로젝트의 마지막으로, useCallback 훅에 대한 사용이 주어져서 이 글의 포스팅을 시작하게 되었다.

    간단히 검색해보니, 이 훅들은 공통적으로 '최적화'의 역할을 담당한다고 한다. 반대로 말하면 필수적이지는 않다는?

     

    최적화의 원리가 되는 'Memoization' 과 여기에 해당되는 위 훅들에 대해 간단하게 정리한 뒤 프로젝트에 돌입하겠다.


    📒 useCallback

    - Memoization 이 필요한 이유?

     

    React 컴포넌트가 렌더링(부모 렌더링, state 변경 등) 될 때마다, 내부의 함수들도 새로 선언한다는 단점이 있다.

    여기서 state와 무관한 함수들의 재선언을 최소화하여 메모리 낭비를 줄이는 최적화의 목적으로 이 Hooks 들이 사용되는 것이다.

     

    - 문법

     

    useCallback 은 컴포넌트 메소드 제작시 포함되며, 함수를 값으로 받아 Memorized 한다.

    const handleChange = useCallback(() => {function}, [dependency array]);
    • function : 기억하고자 하는 기능의 함수가 포함되는 부분이다.
    • dependency array : useEffect와 같이 의존성을 의미한다. 값이 없다면 함수가 한번 실행되고 return 값이 저장됨.
    function App() {
      const [count, setCount] = React.useState(0);
      const memoizedIncrement = React.useCallback(() => {
        setCount(count => count + 1);
      }, [count]);
      const memoizedDecrement = React.useCallback(() => {
        setCount(count => count - 1);
      }, [count]);
      return (
        <>
          Count: {count}
          <button onClick={memoizedDecrement}>Decrement</button>
          <button onClick={memoizedIncrement}>Increment</button>
        </>
      );
    }

    해당 예시를 참고하면, memoizedIncrement, memoizedDecrement 두 함수에 useCallback 이 적용된 것을 알 수 있다.

    만약 이 App 의 부모 컴포넌트가 리렌더되거나, 다른 state 가 선언 및 변경되어도 해당 함수는 리렌더에서 제외된다.


    📒 useMemo

    useMemo 역시 useCallback 과 같은 기능이다. 차이가 있다면 이는 함수가 아닌 return 값을 Memoization 한다는 차이.

     

    - 문법

    const handleChange = useMemo(() => return value, [dependency array]);

    보시다시피, useCallback 과 문법은 유사하다. 함수가 아닌 return value 만 기억한다는 차이가 있다.


    📒 React.memo()

    최적화를 위한 기능으로, 이 React.memo() 메서드도 존재한다. 얼핏 보면 useMemo와 유사해 보이나, 기능은 좀 다르다.

    큰 차이점은, React.memo() 는 컴포넌트를 내부에 래핑하며, 이 컴포넌트에 대한 props를 감지하여 리렌더링을 결정한다.

     

    - 문법(예시)

    export function Movie({ title, releaseDate }) {
      return (
        <div>
          <div>Movie title: {title}</div>
          <div>Release date: {releaseDate}</div>
        </div>
      );
    }
    
    export const MemoizedMovie = React.memo(Movie);

    Movie, MemoizedMovie 모두 같은 Movie 컴포넌트를 렌더링한다.

    차이점은 props(title, releaseDate) 전체적인 변화가 없다면, 해당 DOM은 리렌더링에서 제외된다는 점이다.

    • 장점 : 함수형 컴포넌트가 같은 props로 빈번하게 렌더링되거나, 무겁고 비용이 큰 연산이 있는 경우 유리하다.
    • 단점 : 렌더링마다 props 가 다르면 불필요(비교할 필요가 없음), 클래스형 컴포넌트에 사용하는 것도 부적절

    명심해야 할 점은, 이같은 최적화 툴들은 필요한 경우에 사용하는 것이 그 의의가 극대화된다.

    반대로 얘기하면, 불필요한 남용은 오히려 Memoization 을 위한 메모리 소모가 동반되기 때문이다. 

     

    지금같은 미니 프로젝트에서 활용성은 적겠지만, 향후 큰 규모의 프로젝트에 있어 이 포스팅이 도움이 될 것 같다.

    반응형
Designed by Tistory.