JavaScript[JS]

[React] React hook의 useCallback 이란?

HANdeveloper 2024. 3. 18. 10:20
useCallback
메모이제이션 기법으로 컴포넌트 성능을 최적화 시켜주는 도구

 

💡 메모이제이션 이란?
이전에 계산한 값을 메모리에 저장해두고, 동일하게 다시 사용할 수 있는 곳에서 재사용하여 반복적으로 발생하는 계산의 리소스를 줄이는 기법
  • useMemo() : 자주 쓰이는 값을 메모이제이션 즉 캐싱해주는 것, 그리고 그 값이 필요할 때 다시 계산하는 것이 아닌 useMemo를 통해 캐싱을 한 값을 메모리에서 꺼내와서 재사용하고 인자로 콜백함수를 넣어주면 함수가 리턴하는 값을 메모이제이션 하는 것
  • useCallback() : 인자로 전달한 콜백 함수 그 자체를 메모이제이션하는 것, 첫번째 인자로 넘어온 함수를 두번째 인자로 넘어온 배열 내의 값이 변경될 때까지 정장해놓고 재사용할 수 있게 함

 

📝 useCallback 구조

const memoizedCallback = useCallback(함수, 배열);

 

📝 useCallback 사용예시

1. 콜백함수가 자식 컴포넌트에 props로 전달되는 경우

function ParentComponent() {
  const [count, setCount] = useState(0);
  
  const handleClick = useCallback(() => {
    setCount(prevCount => prevCount + 1);
  }, []);
  
  return (
    <div>
      <ChildComponent onClick={handleClick} />
    </div>
  );
}
 
function ChildComponent({ onClick }) {
  return (
    <button onClick={onClick}>Click me</button>
  );
}

 

handleClick 함수가 ParentComponent 컴포넌트에서 생성되어 ChildComponent 컴포넌트에 props로 전달

만약 useCallback을 사용하지 않으면 ParentComponent가 리렌더링 될 때마다 handleClick 함수가 새로 생성됨

이 경우 ChildComponent는 onClick props가 변경되었으므로 불필요한 리렌더링을 발생

➡️ 이를 방지하기 위해 useCallback을 사용하여 handleClick함수를 메모이제이션함

 

2. 콜백함수가 의존성 배열에 있는 경우

function ParentComponent() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');
  
  const handleChangeText = useCallback((e) => {
    setText(e.target.value);
  }, []); // handleChangeText 함수는 의존성이 없음
  
  const handleClick = useCallback(() => {
    setCount(prevCount => prevCount + 1);
  }, [count]); // handleClick 함수는 count 변수에 의존함
  
  return (
    <div>
      <input type="text" value={text} onChange={handleChangeText} />
      <button onClick={handleClick}>Click me ({count})</button>
    </div>
  );
}

 

handleChangeText 함수는 text 상태만을 참조하므로 의존성 배열이 비어있음

handleClick 함수는 count 상태를 참조하므로 의존성 배열에 count를 추가해줌

count가 변경될 때마다 handleClick함수가 새로 생성됨

➡️ 이를 방지하기 위해 useCallback을 사용하여 handleClick함수를 메모이제이션함

 

3. useEffect와 같이 사용해 컴포넌트 최적화하는 경우

import React, { useCallback, useEffect, useState } from "react";
 
function ExampleComponent(props) {
  const [data, setData] = useState([]);
 
  const fetchData = useCallback(async () => {
    const response = await fetch("https://example.com/data");
    const data = await response.json();
    setData(data);
  }, []);
 
  useEffect(() => {
    fetchData();
  }, [fetchData]);
 
  return (
    <div>
      {data.map((item) => (
        <div key={item.id}>{item.name}</div>
      ))}
    </div>
  );
}
 
export default ExampleComponent;

 

useCallback과 useEffect를 사용하여 데이터를 불러오는 fetchData함수를 최적화해주는 코드

useEffect의 의존성 배열에 fetchData함수를 추가하여, fetchData 함수가 변경될 때에만 useEffect가 실행되도록 함

➡️ 컴포넌트가 렌더링될 때마다 fetchData함수가 새로 생성되는 것을 방지하고, fetchData함수가 변경될 때에만 데이터를 다시 불러오도록 최적화함