본문 바로가기
front-end/React

[React]Hook: useMemo()와 useCallback() / React.memo()

by -제이리 2022. 8. 16.
728x90
320x100

 

useMemo 란? (Hook)

성능 최적화를 위하여 특정 결과값 재사용 할 수 있다.

(useMemo의 Memo는 Memoization을 뜻한다. 이것은 기존에 수행한 연산의 결괏값을 어딘가에 저장해 두고 동일한 입력이 들어오면 재활용하는 프로그래밍 기법이다.)

 

useCallback 이란? (Hook)

성능 최적화를 위하여 특정 함수 재사용 할 수 있다.

 

React.memo 란? (고차 컴퍼넌트(Higher Order Component, HOC)

렌더링 결과를 메모이징(Memoizing)함으로써, 불필요한 리렌더링을 건너뛴다.

오직 props변화에만 의존하는 최적화 방법이다.

 


useMemo(function, deps)

const value = useMemo(() => {
	return fn();
}, [])

파라미터

function: 콜백함수

deps: 의존성 배열.

  • 배열값이 있을 때
    • 배열안에 넣은 내용이 업데이트될 때: 등록한 함수 호출해서 값을 연산해줌
    • 내용변화가 없을 때:  이전에 연산한 값을 재사용해준다.
  • 빈 배열값: 처음 컴포넌트가 마운트 되었을때만 값을 계산해준다(업데이트시 변화 x)

useCallback(function, deps)

const value = useCallback(()=>{},[deps])

파라미터

function: 콜백함수

deps: 의존성 배열.

  • 함수 안에서 사용하는 상태 혹은 props 가 있다면 꼭, deps 배열안에 포함시켜야 된다. props 로 받아온 함수가 있다면, 이 또한 deps 에 넣어주어야 한다.

 


React.memo()

import React from 'react';
import ChildComponent from './ChildComponent';

function ParentComponent(props) {
  // ...

  return (
    <div>
      <h1>Parent Component</h1>
      <ChildComponent prop1={prop1} prop2={prop2} />
    </div>
  );
}

export default React.memo(ParentComponent); //component를 React.memo로 감싼다.

 

😡 기존 문제점: 부모컴포넌트 리렌더링시 자식컴포넌트는 변화가 없어도 무조건 리렌더링 => 불필요한 렌더링 발생

😊 React.memo()사용 시: props체크를 통해 변화가 있을 시에만 렌더링을 해주고 변화가 없으면 렌더링을 하지 않는다. => 불필요한 렌더링 방지

 

언제 사용할까?

  • 컴포넌트가 같은 props로 자주 렌더링 될때
  • 컴포넌트가 렌더링 될때마다 복잡한 로직을 처리해야할때

 

ParentComponent에서 React.memo를 사용하면, ChildComponent의 props가 변경되었을 때 ParentComponent가 다시 렌더링되지 않는다. 그러나 ChildComponent에서 React.memo를 사용하는 것은 권장되지 않는다. ChildComponent의 props가 변경되었을 때, ChildComponent 자체가 다시 렌더링되어야 하기 때문. 따라서, ChildComponent에서 React.memo를 사용하면, 해당 컴포넌트가 렌더링되지 않을 수 있으며, 예기치 않은 결과를 초래할 수 있다.

 

⚠️ props의 값이 객체나 함수일때는 렌더링이 될때 마다 새로운 메모리의 주소값이 주어지기 때문에 메모라이징 되지 않는다.

이럴때는 useMemo나 useCallback 훅을 적절히 사용하여 최적화를 시킬 수 있다. 


memorize 주의점

남용시 컴포넌트의 복잡도가 올라가기 때문에 가독성과 유지보수성이 떨어진다.

또한 적용된 레퍼런스는 재활용을 위해 가비지컬렉션에서 제외되기 때문에 메모리를 더 쓰게 된다.

따라서 성능 최적화를 할때는 사용하는 편이 효율적인지 아닌지 따져보고 사용해야 한다.

728x90
320x100

'front-end > React' 카테고리의 다른 글

[React]Hook: useContext  (0) 2022.08.23
[React] Hook: useReducer  (0) 2022.08.16
[React]Hook: useEffect()  (0) 2022.08.15
Json-server 사용하기 (REST API 구축 라이브러리)  (0) 2022.06.15
[React]git hub배포하기  (0) 2022.05.28

댓글