useCallback은 리렌더링 간에 함수 정의를 캐싱해 주는 React Hook입니다.
const cachedFn = useCallback(fn, dependencies)레퍼런스
useCallback(fn, dependencies)
리렌더링 간에 함수 정의를 캐싱하려면 컴포넌트의 최상단에서 useCallback을 호출하세요.
import { useCallback } from 'react';
export default function ProductPage({ productId, referrer, theme }) {
const handleSubmit = useCallback((orderDetails) => {
post('/product/' + productId + '/buy', {
referrer,
orderDetails,
});
}, [productId, referrer]);매개변수
-
fn: 캐싱할 함숫값입니다. 이 함수는 어떤 인자나 반환값도 가질 수 있습니다. React는 첫 렌더링에서 이 함수를 반환합니다. (호출하는 것이 아닙니다!) 다음 렌더링에서dependencies값이 이전과 같다면 React는 같은 함수를 다시 반환합니다. 반대로dependencies값이 변경되었다면 이번 렌더링에서 전달한 함수를 반환하고 나중에 재사용할 수 있도록 이를 저장합니다. React는 함수를 호출하지 않습니다. 이 함수는 호출 여부와 호출 시점을 개발자가 결정할 수 있도록 반환됩니다. -
dependencies:fn내에서 참조되는 모든 반응형 값의 목록입니다. 반응형 값은 props와 state, 그리고 컴포넌트 안에서 직접 선언된 모든 변수와 함수를 포함합니다. 린터가 React를 위한 설정으로 구성되어 있다면 모든 반응형 값이 의존성으로 올바르게 명시되어 있는지 검증합니다. 의존성 목록은 항목 수가 일정해야 하며[dep1, dep2, dep3]처럼 인라인으로 작성해야 합니다. React는Object.is비교 알고리즘을 이용해 각 의존성을 이전 값과 비교합니다.
반환값
최초 렌더링에서는 useCallback은 전달한 fn 함수를 그대로 반환합니다.
후속 렌더링에서는 이전 렌더링에서 이미 저장해 두었던 fn 함수를 반환하거나 (의존성이 변하지 않았을 때), 현재 렌더링 중에 전달한 fn 함수를 그대로 반환합니다.
주의 사항
useCallback은 Hook이므로, 컴포넌트의 최상위 레벨 또는 커스텀 Hook에서만 호출할 수 있습니다. 반복문이나 조건문 내에서 호출할 수 없습니다. 이 작업이 필요하다면 새로운 컴포넌트로 분리해서 state를 새 컴포넌트로 옮기세요.- React는 특별한 이유가 없는 한 캐시 된 함수를 삭제하지 않습니다. 예를 들어 개발 환경에서는 컴포넌트 파일을 편집할 때 React가 캐시를 삭제합니다. 개발 환경과 프로덕션 환경 모두에서, 초기 마운트 중에 컴포넌트가 일시 중단되면 React는 캐시를 삭제합니다. 앞으로 React는 캐시 삭제를 활용하는 더 많은 기능을 추가할 수 있습니다. 예를 들어, React에 가상화된 목록에 대한 빌트인 지원이 추가한다면, 가상화된 테이블 뷰포트에서 스크롤 밖의 항목에 대해 캐시를 삭제하는것이 적절할 것 입니다. 이는
useCallback을 성능 최적화 방법으로 의존하는 경우에 개발자의 예상과 일치해야 합니다. 그렇지 않다면 state 변수 나 ref가 더 적절할 수 있습니다.
용법
컴포넌트의 리렌더링 건너뛰기
렌더링 성능을 최적화할 때 자식 컴포넌트에 넘기는 함수를 캐싱할 필요가 있습니다. 먼저 이 작업을 수행하는 방법에 대한 구문을 살펴본 다음 어떤 경우에 유용한지 알아보겠습니다.
컴포넌트의 리렌더링 간에 함수를 캐싱하려면 함수 정의를 useCallback Hook으로 감싸세요.
import { useCallback } from 'react';
function ProductPage({ productId, referrer, theme }) {
const handleSubmit = useCallback((orderDetails) => {
post('/product/' + productId + '/buy', {
referrer,
orderDetails,
});
}, [productId, referrer]);
// ...useCallback에게 두 가지를 전달해야 합니다
- 리렌더링 간에 캐싱할 함수 정의
- 함수에서 사용되는 컴포넌트 내부의 모든 값을 포함하고 있는 의존성 목록
최초 렌더링에서 useCallback으로부터 반환되는 함수는 호출시에 전달할 함수입니다.
이어지는 렌더링에서 React는 의존성을 이전 렌더링에서 전달한 의존성과 비교합니다. 의존성 중 하나라도 변한 값이 없다면(Object.is로 비교), useCallback은 전과 똑같은 함수를 반환합니다. 그렇지 않으면 useCallback은 이번 렌더링에서 전달한 함수를 반환합니다.
다시 말하면, useCallback은 의존성이 변하기 전까지 리렌더링 간에 함수를 캐싱합니다.
이 기능이 언제 유용한지 예시를 통해 살펴보겠습니다.
handleSubmit 함수를 ProductPage에서 ShippingForm 컴포넌트로 전달한다고 가정해 봅시다.
function