[React] (리액트 공부하기 16) useCallback

젼이·2025년 1월 9일

리액트 정복하기

목록 보기
16/36

useCallback 이해하기

useCallback은 리액트 컴포넌트에서 함수를 메모제이션(Memoization) 하는 데 사용되는 훅이다.
쉽게 말해, 불필요하게 함수를 다시 생성하지 않고, 이전에 생성한 함수를 재사용 하는 기능을 제공한다.




언제 useCallback을 사용하는가?

컴포넌트가 렌더링될 때마다 함수가 새로 생성되는데, 어떤 상황에서는 매번 새로 생성하지 않고 이전에 생성한 함수를 그대로 재사용하는 것이 성능에 더 유리할 수 있다.


예를 들어:

  • 자식 컴포넌트에 함수를 props로 전달할 때: 부모 컴포넌트가 렌더링될 때마다 새로운 함수가 자식 컴포넌트에 전달 되면, 자식 컴포넌트도 불필요하게 다시 렌더링이 될 수 있다.

  • 비용이 많이 드는 연산을 포함한 함수를 반복적으로 생성하지 않기 위해.




코드 예제와 설명

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

function ParentComponent() {
    const [count, setCount] = useState(0);

    // `useCallback` 없이 작성
    const handleClick = () => {
        console.log("Button clicked");
    };

    return (
        <div>
            <ChildComponent onClick={handleClick} />
            <button onClick={() => setCount(count + 1)}>Increment Parent Count</button>
        </div>
    );
}

function ChildComponent({ onClick }) {
    console.log("Child rendered");
    return <button onClick={onClick}>Click me</button>;
}

사실 이 코드도 나한테는 아직 어렵다.... 하나하나 풀어보자...

전체 코드 구조

  • ParentComponent: 부모 컴포넌트로, count라는 상태(state)를 관리한다.
  • ChildComponent: 자식 컴포넌트로, 버튼을 클릭했을 때 실행될 onClick 이벤트 핸들러를 부모 컴포넌트에서 props로 전달 받는다.

1. useState 이해하기

const [count, setCount] = useState(0);
  • useState: 상태 관리를 위해 사용하는 React 훅이다.

  • count: 현재 상태 값을 나타내는 변수이다. 초기값은 0이다.

  • setCount: 상태를 업데이트하는 함수이다.

  • 호출하면 count의 값이 변경되고, 컴포넌트가 다시 렌더링된다.



2. handleClick 함수

const handleClick = () => {
  console.log("Button clicked");
}
  • handleClick은 간단한 이벤트 핸들러 함수로, 버튼이 클릭될 때 콘솔에 "Button clicked" 메시지를 출력한다.
  • 이 함수는 매번 ParentComponent가 렌더링될 때 새로 생성된다.


3. ChildComponent 컴포넌트

function ChildComponent({ onClick }) {
  console.log("Child rendered");
  return <button onClick={onClick}>Click me</button>;
}
  • ChildComponent:
  • props로 전달받은 onClick을 버튼의 onClick 이벤트로 연결한다.
  • console.log("Child rendered"): ChildComponent가 렌더링될 때마다 콘솔에 메시지를 출력한다.


4. ParentComponent의 버튼

<button onClick={() => setCount(count + 1)}>Increment Parent Count</button>
  • setCount(count +1):
  • 버튼 클릭 시 count의 값을 1 증가 시킨다.
  • count가 변경되면 ParentComponent가 다시 렌더링이 된다.



실행 흐름

  1. 초기 렌더링:
  • ParentComponent가 렌더링이 된다.
  • ChildComponent가 렌더링되고, "Child rendered" 메시지가 콘솔에 출력된다.
  1. "Increment Parent Count"버튼 클릭:
  • setCount가 호출되어 count가 1증가한다.
  • ParentComponent가 다시 렌더링이 된다.
  • 새로운 handleClick 함수가 생성 된다.
  • 새로운 handleClick이 ChildComponent에 props로 전달되므로, ChildComponent도 다시 렌더링 된다.
  1. "Click me" 버튼 클릭:
  • handleClick 함수가 호출되어 "Button clicked" 메시지가 콘솔에 출력된다.


문제점

ParentComponent가 렌더링될 때마다 새로운 handleClick 함수가 생성된다.
React는 props가 변경되면 자식 컴포넌트를 다시 렌더링하므로, ChildComponent가 불필요하게 다시 렌더링이 된다.




useCallback을 적용

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

function ParentComponent() {
    const [count, setCount] = useState(0);

    // `useCallback` 적용
    const handleClick = useCallback(() => {
        console.log("Button clicked");
    }, []); // 의존성 배열이 비어 있으므로 handleClick은 항상 동일한 함수 참조를 유지

    return (
        <div>
            <ChildComponent onClick={handleClick} />
            <button onClick={() => setCount(count + 1)}>Increment Parent Count</button>
        </div>
    );
}

function ChildComponent({ onClick }) {
    console.log("Child rendered");
    return <button onClick={onClick}>Click me</button>;
}

위 코드에서 useCallback을 사용하면, handleClick 함수가 매번 새로 생성되지 않고, 항상 동일한 함수를 사용하게 된다. 따라서 ChildComponent는 불필요하게 다시 렌더링이 되지 않는다.




핵심 요약

  1. useCallback이란?
  • 함수를 메모이제이션하여 렌더링 시 동일한 함수를 재사용
  • 의존성 배열에 있는 값이 변경되지 않는 한, 함수가 새로 생성되지 않음.
  1. 언제 사용해야 하는가?
  • 자식 컴포넌트에 props로 전달되는 함수를 매번 새로 생성하지 않으려 할 때.
  • 비싼 연산이 포함된 함수가 반복적으로 생성되지 않도록 최적화 할 때.
  1. 사용법
const memoizedCallback = useCallback(
  () => {
    // 실행할 함수
  },
  [dependency1, dependency2] // 의존성 배열
);

useCallback은 최적화 도구이므로, 모든 경우에 사용하지 않아도 된다. 성능상의 이점이 필요한 경우에만 적용한다.

profile
신입 개발자 임니당 : > (2025.02.05~)

0개의 댓글