useCallback

✒️ 2025-05-28 10:43 내용 수정


리렌더 사이의 함수 정의를 캐시할 수 있도록 하는 Hook

const cachedFn = useCallback(fn, dependencies);
import { useCallback } from 'react';

function TestPage({id, name, theme='dark'}) {

	// Javascript는 특성 상 항상 다른 함수를 생성한다
    // useCallback() 사용시 리렌더링 사이에 handleClick()을 캐싱하도록 지시
	const handleClick = useCallback(()=>{ 
        console.log(id, name);
	}, [id, name]); // id와 name이 변경되지 않는 한 useCallback()으로 반환되는 함수는 동일한 함수다

    return(
		//...
    )
}

export default TestPage;
function App() {
	return(
		{/* TestPage component에 id와 name을 전달 */}
		<TestPage id={1} name={'test'}/>
	)
}

export default App;
import { useCallback, memo } from 'react';

export default function TestPage({id, name, theme='dark'}) {

    // useCallback()을 사용하지 않았다면 handleClick()은 theme이 변경될 때마다 매번 변경됨
    // useCallback() 사용시 리렌더링 사이에 handleClick()을 캐싱하도록 지시
	const handleClick = useCallback(()=>{
        console.log(id, name);
	}, [id, name]); // id와 name이 변경되지 않는 한 Test Component에 전달되는 함수는 동일한 함수

    return(
        <div className={theme}>
            <Test handleClick={handleClick}/>
        </div>
    )
}

// 1. theme을 받지 않는 Test Component는 theme의 변경에 무관하므로 memo()로 감싸게 되면
// Test Component의 모든 props가 마지막 렌더링과 동일할 때 리렌더링을 건너뛰도록 지시할 수 있다

// 2. handleClick()이 useCallback()으로 저장되지 않았다면 Test Component가 전달받은 handleClick()는 
// theme가 변경될 때마다 매번 새로 생성된 함수이므로 이전 렌더링과 같지 않아 매번 리렌더링 됬을 것
/* 
function handleClick() { // 이런 경우 theme이 변경될 때 매번 달라지는 함수가 된다
	console.log(id, name);
}
*/

// 3. handleClick()이 useCallback()으로 캐싱되었다면 id와 name이 변경되지 않는 한 이전 렌더링과 동일한 함수를 저장하므로
// Test Component는 동일한 props를 가지게 되어 리렌더링을 건너 뛸 수 있음
const Test = memo(function Test({ handleClick }) {
    return (
        <button onClick={handleClick}>클릭</button>
    )
})
// 간소화된 구현체
function useCallback(fn, dependencies) {
	return useMemo(()=> fn, dependencies);
}