useCallback은 인자로 넣은 함수를 memoizing해서 component가 re-rendering 될 때 재정의되는 것을 막아준다.
사용 시에 함수 내부에서 사용한 state를 반드시 dependencies에 넣어줘야 정상적으로 동작하는데, 그럴거면 왜 넣는건가? 라는 생각이 들어 dependencies를 비우고 동작시켜봤다.
const [bool, setBool] = useState(false);
const handlePrint = useCallback(() => console.log(bool), []);
const handleToggle = useCallback(() => setBool((prev) => !prev), []);
return (
<button onClick={handleToggle}>toggle</button>
<button onClick={handlePrint}>print</button>
)
아래의 순서대로 조작했다.
print
button clicktoggle
button clickprint
button click결과는 아래와 같다.
false
false
이번엔 조금 추가해서, 원시타입 변수와 참조타입 변수를 추가해서 동일한 순서로 조작했다.
const [bool, setBool] = useState(false);
const refVal = [false];
let priVal = false;
const handlePrint = useCallback(() => {
console.log(bool, refVal[0], priVal);
}, []);
const handleToggle = useCallback(() => {
setBool((prev) => !prev);
refVal[0] = true;
priVal = true;
}, []);
결과는 아래와 같다.
/* state, 참조타입, 원시타입 */
false false false
false true true
정작 state는 변하지 않고, 원시타입과 참조타입의 변수값이 바뀌었다.
"useCallback은 재정의되지 말라고 쓰는건데, state를 dependencies에 넣으면 의미가 없지 않나?"
라는 생각에 빼봤는데, 제법 터무니없는 결과가 나와서 신기한 마음에 기록해본다.
원인은 깊게 찾아보지 않았는데, 플젝 최적화 작업이 어느정도 완성되면 찾아봐야겠다.