[TIL #9] React (Hooks) - useMemo, useCallback 이란?

JMinkyoung·2021년 7월 14일
0

TIL

목록 보기
9/42
post-thumbnail

앞에서 다뤘듯이 React 16.8에 새롭게 추가된 개념인 Hook API에는 가장 기본적인 useState, useEffect, useContext 이 있었다. 그 외에도 추가적인 Hooks들이 있는데 그 중에서 함께 자주 언급되고 많이 사용되고 있는 useMemo, useCallback을 자세히 다뤄볼 것이다 🧐

useMemo

useMemo 란?

React 공식문서에 적혀있는 useMemo의 기본 구조는 다음과 같다.

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

성능 최적화를 위해 도입된 useMemo메모이제이션된 값을 반환하며, 특정 값이 변경되었을 때만 입력한 연산을 실행하고, 값이 그대로라면 직전에 연산했던 결과를 그대로 다시 사용하는 방법이다.

또한 useMemo를 통해 전달된 연산(함수)는 렌더링을 하는 중에 실행되기 때문에 렌더링 중에는 하지않는 Side Effect는 useMemo가 아닌 useEffect에서 실행되어야 한다!

⚡Side Effect 란?
컴포넌트가 화면에 렌더링된 이후에 비동기로 처리되어야 하는 부수적인 효과들을 의미한다.

useMemo 예제

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

const App = () => {

  const [name, setName] = useState("");
  const nameLength = useMemo(()=> name.length, [name]);

  const updateName = (e) => {
    setName(e.target.value);
  };

  return (
    <div>
      <input onChange={updateName}></input>
      <h3>이름의 길이는 {nameLength} 입니다.</h3>
    </div>
  );
};

export default App;


input을 통해 이름을 입력받고 useState를 이용해 이름을 변경해주고, 이름이 변경될 때 마다 useMemo를 이용하여 이름의 길이를 측정하는 간단한 예제이다.

const nameLength = useMemo(()=> name.length, [name]);

핵심 코드를 보면 nameLength라는 메모리제이션 될 값을 선언하고 useMemo를 이용하여 name의 변경 여부를 확인하며 변경시에는 name.length를 이용하여 길이 계산하고 nameLength에 대입하게 된다.

useCallback

useCallback 이란?

React 공식문서에 적혀있는 useCallback의 기본 구조는 다음과 같다.

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

useCallback 역시 마찬가지로 성능 최적화를 위해 도입되었으며 메모이제이션된 콜백을 반환한다. 즉 원하는 때에만 콜백 함수를 생성할 수 있다. useCallback의 첫번째 파라미터에는 생성하고 싶은 함수를 적고, 두번째 파라미터에는 어떠한 값을 넣게 되는데, 이 값이 변할때 첫번째 파라미터의 함수가 생성되는 구조이다.

useCallback 예제

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

const App = () => {

  const [name, setName] = useState("");
  const [nameLength, setNameLength] = useState(0);

  // 첫 렌더링시에만 함수가 생성된다.
  const updateName = useCallback((e)=> {
    setName(e.target.value);
  },[]);

  // name값이 변경될 때에만 함수가 생성된다.
  const updateNameLength = useCallback(()=>{
    setNameLength(name.length);
  },[name]);

  return (
    <div>
      <input onChange={updateName}></input>
      <button onClick={updateNameLength} >입력</button>
      <h3>이름의 길이는 {nameLength} 입니다.</h3>
    </div>
  );
};

export default App;


input을 통해 이름을 입력받고 button을 누르면 이름의 길이를 useState를 이용하여 업데이트 해주는 예제이다.

// 리렌더링 될 때 마다 생성된다.
const updateName = (e) => {
   setName(e.target.value);
};

 // 첫 렌더링시에만 함수가 생성된다.
 const updateName = useCallback((e)=> {
   setName(e.target.value);
 },[]);

핵심 코드를 보면 useMemo의 예제에서의 updateName 함수와는 다르게 이번 예제에서는 useCallback을 사용하여 빈 배열 값을 넣어줬기 때문에 첫 렌더링시에만 해당 함수가 생성된다.

// name값이 변경될 때에만 함수가 생성된다.
  const updateNameLength = useCallback(()=>{
    setNameLength(name.length);
  },[name]);

button을 클릭 할 시 수행되는 함수인 updateNameLength의 경우에는 배열에 name값을 넣어주었기 때문에 name값이 변경될 때에만 함수가 생성되게 된다.

useMemo : 렌더링하는 중에 특정 값이 변경되었을 때만 전달된 연산을 실행하고, 값이 그대로라면 그 전에 했던 연산 결과를 그대로 다시 사용한다. 즉 전달된 함수가 실행되고 반환된 결과를 저장한다.

useCallback : 사용자가 원하는 때에만 전달되는 함수를 생성할 수 있으며, 전달된 함수 그 자체를 저장한다.

profile
Frontend Developer

0개의 댓글