본문 바로가기

이것저것 스터디📚/React - 공식 문서

React 공식문서 -useCallback

- useCallback은 리렌더링 사이에서 함수 정의를 캐시할 수 있게 해주는 React 훅이다.

 

Parameters(매개변수)

- fn : 캐시하려는 함수 값. 어떤 인자도 받을 수 있고 어떤 값이라도 반환할 수 있다.

- dependencies : fn 코드 내에서 참조된 모든 반응형 값의 배열

 

Returns(반환 값)

- 초기 렌더링에서 useCallback은 전달한 fn 함수를 반환한다.

- 렌더링 중 : 마지멕 렌더링에서 이미 저장된 fn 함수 또는 렌더링 중에 전달했던 fn 함수 반환


* How is useCallback related to useMemo(useCallback과 useMemo는 무슨 관련이 있을까요?)

- 공통점 : 자식 컴포넌트를 최적화하려고 할 때, 두 가지 모두 유용하다.

- 차이점

1. useMemo는 호출한 함수 결과를 캐시한다.

2. useCallback은 함수 자체를 캐시한다.

 

- useMemo에 익숙하다면, useCallback을 이렇게 생각해볼 수 있다.

// Simplified implementation (inside React)
// 간소화된 구현체 (React 내부)
function useCallback(fn, dependencies) {
  return useMemo(() => fn, dependencies);
}

Optimizing a custom Hook(커스텀 훅 최적화하기)

- 커스텀 훅을 작성하는 경우 반환하는 모든 함수를 useCallback으로 감싸는 것이 좋다.

function useRouter() {
  const { dispatch } = useContext(RouterStateContext);

  const navigate = useCallback((url) => {
    dispatch({ type: 'navigate', url });
  }, [dispatch]);

  const goBack = useCallback(() => {
    dispatch({ type: 'back' });
  }, [dispatch]);

  return {
    navigate,
    goBack,
  };
}

I need to call useCallback for each list item in a loop, but it's not allowed(루프 안에서 목록의 각 항목에 useCallback를 호출하려 하는데, 허용되지 않는다고 합니다.)

function ReportList({ items }) {
  return (
    <article>
      {items.map(item => {
        // 🔴 You can't call useCallback in a loop like this:
        // 🔴 useCallback는 루프 안에서 호출할 수 없습니다:
        const handleClick = useCallback(() => {
          sendReport(item)
        }, [item]);

        return (
          <figure key={item.id}>
            <Chart onClick={handleClick} />
          </figure>
        );
      })}
    </article>
  );
}

- 위 예제에서처럼 반복문에서는 useCallback을 호출할 수는 없다.

// 개별 항목에 대한 컴포넌트를 추출하고 거기에 useCallback을 넣는 방법
function ReportList({ items }) {
  return (
    <article>
      {items.map(item =>
        <Report key={item.id} item={item} />
      )}
    </article>
  );
}

function Report({ item }) {
  // ✅ Call useCallback at the top level:
  // ✅ useCallback은 컴포넌트의 최상위 레벨에서 호출하세요:
  const handleClick = useCallback(() => {
    sendReport(item)
  }, [item]);

  return (
    <figure>
      <Chart onClick={handleClick} />
    </figure>
  );
}

// useCallback 대신 memo를 사용하는 방법
function ReportList({ items }) {
  // ...
}

const Report = memo(function Report({ item }) {
  function handleClick() {
    sendReport(item);
  }

  return (
    <figure>
      <Chart onClick={handleClick} />
    </figure>
  );
});

* 참고 : React 공식문서(https://react-ko.dev/learn)