리액트

[React]memo(React.memo), useCallback,useMemo

민ズl 2024. 11. 5. 16:56

React의 렌더링 조건

  • props 변경될때마다
  • state가 변경될때마다

💩 부모 컴포넌트가 다시 렌더링되면 해당 모든 자식의 컴포넌트도 불필요하게 다시 렌더링될 수 있음!

이를 위해 사용하는 것들👇👇👇

memoization

  • 처음 계산해 놓은 결과를 메모리상에 저장해 두고, 그 저장된 메모리 주소를 필요할때 꺼내서 사용하는 방법
  • 반환값을 캐싱하는 것
  • 최적화 기법

memo(React.memo)

  • 자식 컴포넌트를 메모이제이션함
  • 리액트 고차 컴포넌트(HOC)임
    * 고차 컴포넌트(HOC) : 어떤 컴포넌트를 인자로 받아서 최적화된 새로운 컴포넌트로 반환
  • 🚫꼭 필요할때만 사용하기
    1. 컴포넌트가 같은 props로 자주 렌더링 될때
    2. 컴포넌트가 렌더링이 될때마다 복잡한 로직을 처리해야 할때
  • 오직 Props 변화에만 의존하는 최적화 방법

but, 부모 컴포넌트가 렌더링될때마다 객체나 함수 props가 새로운 참조 값으로 생성되기때문에
자식 컴포넌트가 React.memo로 감싸져 있더라도 재렌더링이 발생할 수 있음!💩

그래서 이때 참조하는게 함수면 useCallback, 값이면 useMemo를 사용하여 재렌더링 방지!🌟

useCallback

  • 함수를 메모이제이션하여 부모 컴포넌트가 다시 렌더링되더라도 같은 참조를 유지하게 하는 hook
  • 인자로 들어오는 함수 자체를 메모이제이션함
  • 콜백함수, 의존성 배열을 받음
  • 렌더링 => component 함수 호출 => memoize 된 함수를 재사용

useMemo

  • 을 메모이제이션하여 부모 컴포넌트가 다시 렌더링되더라도 같은 참조를 유지하게 하는 hook
  • 콜백함수 , 의존성배열을 받음
  • return하는 값을 메모이제이션함
  • useMemo를 남발하면 별도의 메모리 확보를 너무나 많이 하게 되기 때문에 오히려 성능이 악화💩
    ∴ 성능 최적화를 위해서만 사용
import { useMemo } from 'react';
import { filterTodos } from './utils.js'; //무거운 작업

export default function TodoList({ todos, theme, tab }) {
  const visibleTodos = useMemo(
    () => filterTodos(todos, tab),
    [todos, tab]
  );
  return (
    <div className={theme}>
      <p><b>Note: <code>filterTodos</code> is artificially slowed down!</b></p>
      <ul>
        {visibleTodos.map(todo => (
          <li key={todo.id}>
            {todo.completed ?
              <s>{todo.text}</s> :
              todo.text
            }
          </li>
        ))}
      </ul>
    </div>
  );
}

*useCallback은 함수를, useMemo는 값을!

  • 렌더링시 함수 내부 변수는 초기화됨
  • 초기화가 된다는건 새로운 객체가 다시 만들어지고, 메모리 주소도 새로 생성이 됨
    => 렌더링 전 변수와 렌더링 후 변수는 다름
  • useEffect에서 의존성 배열은 결국 무한 렌더링이 발생
  • 이를 해결하기 위해 useCallback, useMemo를 사용하여 함수 자체를 memoization해줌!

'리액트' 카테고리의 다른 글

[React]context api  (0) 2024.11.11
[React]form태그 비제어  (0) 2024.11.06
[React]useContext  (0) 2024.11.04
[React]useRef  (0) 2024.11.04
[React]useEffect  (1) 2024.11.04