728x90
728x90

useCallback 훅

들어가며

  • 리액트(React.js)에서 사용되는 @useCallback@ 훅에 대해 정리해본다.

 

useCallback 훅

개념

  • 컴포넌트의 성능 최적화(Optimization)를 위해 자주 사용되는 훅
  • 함수를 메모이제이션(Memoization)하여 컴포넌트가 리렌더링될 때마다 함수가 재생성되는 것을 방지한다.

 

사용 방법

  • @useCallback(() => {}, [])@와 같이 사용한다.
    • 첫 번째 인자로 함수를 받고, 두 번째 인자로 의존성 배열(Dependencies Array)을 받는다.
const memoizedCallback = useCallback(() => {
  doSomething(a, b);
}, [a, b]);

 

⇒ 리액트는 컴포넌트가 리렌더링될 때마다 해당 함수를 다시 생성하지 않고, 의존성 배열에 있는 값들이 변경될 때만 함수를 새로 생성한다.

⇒ 불필요한 함수 재생성을 막고, 자식 컴포넌트로 전달된 함수가 불필요하게 변경되어 불필요한 리렌더링이 발생하는 것을 방지한다.

 

import { useState, useCallback } from 'react';

import { data } from '../data';

import List from './components/List3';

const UseCallbackExample = () => {
  const [people, setPeople] = useState(data);
  const [count, setCount] = useState(0);

  const removePerson = useCallback(
    (id) => {
      const newPeople = people.filter((person) => person.id !== id);
      setPeople(newPeople);
    },
    [people]
  );

  return (
    <div className="section">
      <h1>useCallback Example</h1>
      <section>
        <button
          className="btn"
          onClick={() => setCount(count + 1)}
          style={{ marginBottom: '1rem' }}
        >
          count {count}
        </button>
        <List people={people} removePerson={removePerson} />
      </section>
    </div>
  );
};

export default UseCallbackExample;

 

자식 컴포넌트(<List/>)로 전달된 함수(removePerson)가 불필요하게 변경되어 불필요한 리렌더링이 발생하는 것을 방지한다.

 

사용해야 할 때

  1. 자식 컴포넌트에 함수를 @props@로 전달하는 경우
  2. 컴포넌트가 자주 리렌더링되거나, 큰 리스트를 처리할 때와 같이 성능 이슈가 있을 경우
  3. @useEffect@나 @useMemo@와 함께 사용할 때, 의존성 배열의 값들이 변경될 때만 함수를 다시 생성하고 싶을 경우

 

사용 시 주의할 점

  • @useCallback@ 훅을 남용할 경우, 오히려 코드가 복잡해지고 성능에 도움이 되지 않는 경우가 있다.
    • 따라서, 최적화가 필요한 경우에만 사용하는 것이 좋다.

 

사용 예

  • 깃허브(GitHub) API를 이용하여 유저 정보를 불러오는 코드이다.
  • @useEffect@ 훅을 이용하여 데이터를 불러와도 의존성 배열(@[]@)이 비어 있어서, 처음에 한 번만 실행되지만, 컴포넌트가 리렌더링 될 때마다 데이터가 다시 불러와지는 현상이 발생한다.
  • 이 현상을 방지하기 위해서, @useCallback@ 훅을 이용하여 처음 컴포넌트가 생성될 때 딱 한 번만 데이터가 불러와지도록 할 수 있다.
    • @fetchData@ 함수가 처음 렌더링 시 한 번만 생성되고, 이후 리렌더링 시에도 함수가 재생성되지 않는다.
import { useState, useEffect, useCallback } from 'react';
const url = 'https://api.github.com/users';

const FetchData = () => {
  const [users, setUsers] = useState([]);
  
  const fetchData = useCallback(async () => {
    try {
      const response = await fetch(url);
      const users = await response.json();
      setUsers(users);
    } catch (error) {
      console.log(error);
    }
  }, []);

  useEffect(() => {
    fetchData();
  }, [fetchData]);
  
  //...
};

 

참고 사이트

 

useCallback – React

The library for web and native user interfaces

ko.react.dev

 

728x90
728x90