[React] useCallback을 사용하여 함수 재사용하기

Hyeon·2021년 7월 11일
0

React

목록 보기
4/6
post-thumbnail

useCallback은 useMemo와 비슷한 Hook이다.
useMemo는 특정 결과값을 재사용할 때 사용하는 반면, useCallback은 특정 함수를 새로 만들지 않고 재사용하고 싶을 때 사용한다. 주로 랜더링 성능을 최적화해야 하는 상황에서도 사용한다.

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 = e => {
    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> {avg}
      </div>
    </div>
  );
};

onChange, onInsert 라는 함수를 선언을 하게 되면 컴포넌트가 리랜더링 될 때마다 이 함수들이 새로 생성되게 된다. 함수를 선언하는 것 자체는 메모리, CPU, 리소스를 많이 차지하는 작업은 아니기 때문에 큰 부하가 생길 일은 없지만, 한번 만든 함수를 필요할 때만 새로 만들고 재사용하는 것은 중요하기 때문에 최적화를 하는 것이 좋다.

useCallback을 사용하여 최적화를 해보자.

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

  const onChange = useCallback(e => {
    setNumber(e.target.value);
  }, []); // 컴포넌트가 처음 렌더링 될 때만 함수 생성
  const onInsert = useCallback(
    e => {
      const nextList = list.concat(parseInt(number));
      setList(nextList);
      setNumber('');
    },
    [number, list]
  ); // number 혹은 list 가 바뀌었을 때만 함수 생성

useCallback의 첫 번째 파라미터에는 우리가 생성해주고 싶은 함수를 넣어주고, 두 번째 파라미터에는 배열(deps)을 넣어주면 되는데 이 배열에는 어떤 값이 바뀌었을 때 함수를 새로 생성해주어야 하는지 명시해주어야 한다.

함수의 내부에서 기존의 상태 값을 의존해야 할 때는 deps 배열 안에 꼭 포함시켜야 된다. 배열 안에 값을 넣지 않게 된다면 onInsert와같이 함수 내에서 numberlist의 값들을 조회할 때 가장 최신 값을 참조할 것이라고 보장할 수 없다.


다음 두 코드는 useCallbackuseMemo를 사용한 같은 기능을 하는 코드이다.

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

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

useCallback은 결국 useMemo에서 함수를 반환하는 상황에 더 편하게 사용할 수 있는 Hook이다. 숫자, 문자열, 객체처럼 일반 을 재사용하기 위해서는 useMemo를, 함수를 재사용 하기 위해서는 useCallback을 사용한다.

출처
https://react.vlpt.us/basic/18-useCallback.html
https://thebook.io/080203/ch08/05/
https://velog.io/@velopert/react-hooks

0개의 댓글