사이드 프로젝트를 진행하며, 생각보다 메인 컴포넌트에 연산 로직이 많아지고 코드가 길어지니... 이를 하나 둘씩 리팩토링 해야했고 드디어 이들이 등장했다!🫢
useCallback은 컴포넌트가 리렌더링 될 때마다 콜백함수를 매번 새로 생성하지 않고, 재사용하여 성능 최적화에 기여하는 훅을 의미한다.
특히 해당 함수를 자식 컴포넌트의
props로 전달해야 한다면, 자식 컴포넌트의 불필요한 렌더링을 방지해주니 더욱 사용을 고려해봐도 좋다.
(props로 전달한다면React.memo와 함께)
const cachedFn = useCallback(fn, dependencies)
useCallback을 감싼다.의존성 배열에
값이 빈 경우 : 처음 한 번만 함수가 생성되고, 이후에는 재생성되지 않음
값이 들어간 경우 : 해당 값이 변경될 때만 새로운 함수 생성
import React, { useState, useCallback } from "react";
import ChildComponent from "./ChildComponent";
const ChildComponent = React.memo(({ onClick }: { onClick: () => void }) => {
return <button onClick={onClick}>+</button>;
});
export const ParentComponent = () => {
const [count, setCount] = useState(0);
// useCallback으로 함수의 참조값을 유지 (불필요한 리렌더링 방지)
const handleClick = useCallback(() => {
setCount((prev) => prev + 1);
}, []);
return (
<div>
<p>Count: {count}</p>
<ChildComponent onClick={handleClick} />
</div>
);
};
useCallback을 사용하면 동일한 함수 참조값을 유지하여 불필요한 리렌더링을 방지useMemo는 무거운 연산이 렌더링마다 실행되지 않도록 캐싱하여 성능 최적화에 기여하는 훅을 의미한다.
const cachedValue = useMemo(calculateValue, dependencies)
useMemo을 감싼다.import React, { useState, useMemo } from "react";
export const Component = () => {
const [count, setCount] = useState(0);
const [numbers] = useState([5, 2, 8, 1, 3]);
// useMemo를 사용하여 정렬된 배열을 캐싱
const sortedNumbers = useMemo(() => {
return [...numbers].sort((a, b) => a - b);
}, [numbers]); // numbers가 변경될 때만 정렬 로직 실행
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
<p>Sorted Numbers: {sortedNumbers.join(", ")}</p>
</div>
);
};
useMemo는 값을 캐싱하여 불필요한 연산을 방지하는 역할무엇을 메모이제이션(기억)하여 재사용하는가?
useCallback는 함수를 메모이제이션useMemo는 값을 메모이제이션