useMemo와 달리 함수 자체를 memoize한다.
// calculate 변수는 memoize된 함수를 가지게 된다.
const calculate = useCallback((num) => {
return num + 1;
}, [item])
useMemo와 동일하게 콜백함수와 의존성 배열로 구성되어 있는데,
useCallback의 memoize된 함수는 의존성 배열 내부에 있는 값이 변경되지 않는 이상 초기화되지 않는다.
import React, { useEffect, useState } from 'react'
const App = () => {
const [number, setNumber] = useState(0);
const sumFunction = () => {
console.log(`number : ${number}`)
return;
}
useEffect(()=>{
console.log("sumFunction이 변경되었습니다.")
},[sumFunction])
return (
<div>
<input
type='number'
value={number}
onChange={(e) => setNumber(e.target.value)}/>
<br/>
<button type='button' onClick={sumFunction}>call sumFunction</button>
</div>
)
}
export default App
useEffect로 sumFunction 변수안의 함수가 어떻게 작동하는지 우선 알아보자.
input number를 올려줄때마다 위와 같이 sumFunction 함수가 계속해서 불러와 질 것이다.
왜냐면 랜더링 되어서 sumFunction이라는 함수도 초기화 되었다가 다시 불러와지니까!
이제 useCallback으로 감싸주겠다.
const sumFunction = useCallback(() => {
console.log(`number : ${number}`)
return;
},[])
이렇게 써주고 숫자를 올려줘보면 이제 더이상 sumFunction이 계속 불러와지진 않는다.
그런데 숫자를 올려주고 button을 눌러서 sumFunction을 확인해보면,
올려준 숫자만큼 반영되어 있지 않다는것을 확인할 수 있다…
5까지 숫자를 올려줬으면 5가 출력되어야하는데 0이 출력되는것을 볼 수 있음.
의존성 배열을 비워뒀기 때문이다.
배열을 비워두면 첫번째 상태값만 memoize해두고 그것을 재사용하기 때문!!
const sumFunction = useCallback(() => {
console.log(`number : ${number}`)
return;
},[number])
그래서 의존성 배열에다가 number가 바뀔때 함수를 다시 저장할 수 있도록 처리해 주자.
저렇게 해주면 이제
number값이 바뀔때 마다, useEffect가 다시 계속해서 실행되어지게 된다.
왜냐면 number 바뀌는 시점마다 함수를 다시 새로 저장하니까!
그리고 button을 누르면, 변경된 number값이 제대로 출력되는 것을 확인할 수 있다.
const [size, setSize] = useState(100);
const [theme, setTheme] = useState(false);
const createBoxStyle = () => {
return{
backgroundColor: "pink",
width:`${size}px`,
height:`${size}px`,
}
}
const changeTheme = () => {
setTheme(!theme)
}
위와 같이 여러가지 함수들이 한 컴포넌트에 존재할 때,
한가지의 동작만 했더라도 렌더링이 되면서 모든 함수들이 초기화 되었다가 동시에 불러와지게 된다.
쉽게말해, 사이즈 변경만 해줬는데 사실은 theme도 불러와진것.
const createBoxStyle = useCallback( () => {
return{
backgroundColor: "pink",
width:`${size}px`,
height:`${size}px`,
}
},[size])
그럴때 위와 같이 useCallback을 활용해서 size가 변경되어질 때에만 불러와져라라고 설정 가능한 것이다.