useCallback vs useMemo

백승용·2021년 4월 4일
0

React

목록 보기
5/14
import React, { useState, useMemo } from "react";

const getAverage = (numbers) => {
  console.log("평균값 계산 중..");
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a, b) => a + b);
  return sum / numbers.length;
};

const Average = () => {
  const [list, setList] = useState([]);
  const [number, setNumber] = useState("");

  const onChange = (e) => {
    setNumber(e.target.value);
  };
  const onInsert = () => {
    const nextList = list.concat(parseInt(number));
    setList(nextList);
    setNumber("");
  };

  const avg = useMemo(() => getAverage(list),[list])

  return (
    <div>
      <input value={number} onChange={onChange} />
      <button onClick={onInsert}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <div>
        {/* <b>평균값:</b> {getAverage(list)} */}
        <b>평균값:</b> {avg}
      </div>
    </div>
  );
};

export default Average;

useMemo??

Memo는 "memoized"를 의미하는데, 이전에 계산한 값을 재사용한다는 의미를 가지고 있다. 첫번째 파라미터에는 어떻게 연산할지 정의하는 함수를 넣고 두번째 파라미터에는 배열을 넣어준다. 두번째 파라미터의 값이 변경되면 첫번째에 넣어준 함수를 호출하여 연산하고 바뀌지 않았다면 이전에 연산한 값을 재사용하게 된다.
getAverage함수를 통해 평균값을 구하고 있다. 하지만 인풋 내용이 바뀔 때마다 리렌더링 되면서 다시 계산하고 있는데 이는 낭비가 된다. 그래서 useMemo를 사용하여 list가 변할 때만 계산하도록 하였다.(useMemo(() => getAverage(list),[list]))

useCallback??

useMemo는 특정 결과값을 재사용할 때 사용하는 반면, useCallback은 특정 함수를 새로 만들지 않고 재사용하고 싶을때 사용한다.
useCallback은 이벤트 핸들러 함수를 필요할 때만 생성할 수 있다. 주로 렌더링 성능을 최적화해야 하는 상황에서 사용한다.
useCallback의 첫 번째 파라미터에는 생성하고 싶은 함수를 넣고, 두 번째 파라미터에는 배열을 넣으면 된다. 이 배열에는 어떤 값이 바뀌었을 때 함수를 새로 생성해야 하는지 명시해야 한다. 다시 말하자면, 첫 번째 파라미터에 넣은 함수는 두 번째 파라미터인 배열 안에 값이 바뀌었을 때 함수를 새로 생성한다.

그럼 두 번째 파라미터는 어떨 때 넣어야되는가하면 함수 내부에서 상태 값에 의존해야 할 때는 그 값을 반드시 두 번째 파라미터 안에 포함시켜 주어야 한다.

코드를 보면 onInsert함수에서 list와 number를 조회(list.concat(parseInt(number)))해서 nextList를 생성하기 때문에 배열 안에 number와 list를 꼭 넣어 주어야한다.

두 번째 파라미터에 빈 배열을 넣었을 때는 컴포넌트가 렌더링될 때 단 한번만 함수가 생성된다.

useCallback vs useMemo

다음 두 코드는 완전히 똑같은 코드이다. 숫자, 문자열, 객체처럼 일반 값을 재사용하려면 useMemo를 사용하고, 함수를 재사용하려면 useCallbackk을 사용한다.

useCallback(() => {
  console.log('hello world!');
}, [])

useMemo(() => {
  const fn = () => {
    console.log('hello world!');
  }
  return fn;
}, [])

0개의 댓글