2월 11일 여정 34일차이다.
useCallback은 인자로 들어오는 함수를 기억한다.
오늘은 useCallback이라는 Hook에 대해 알아보려고 한다.
useCallBack이란 무엇인가?
인자로 들어오는 함수 자체를 기억하는 hook이다.
가령 예를 들어서 어떤 React 컴포넌트 함수 안에 함수가 선언이 되어 있다면
이 함수는 해당 컴포넌트가 랜더링 될 때 마다 새로운 함수가 생성된다.
그렇지만 useCallback()을 사용하면 랜더링이 되더라도 함수가 가지고 있는 값들이
바뀌지 않는 한 기존 함수를 계속 반환하게 된다.
// count를 초기화해주는 함수
const initCount = () => {
console.log(`[COUNT 변경] ${count}에서 0으로 변경되었습니다.`);
setCount(0);
};
return (
<>
<h3>카운트 예제입니다!</h3>
<p>현재 카운트 : {count}</p>
<button onClick={onPlusButtonClickHandler}>+</button>
<button onClick={onMinusButtonClickHandler}>-</button>
<div style={boxesStyle}>
<Box1 initCount={initCount} />
<Box2 />
<Box3 />
</div>
</>
);
}
function Box1({ initCount }) {
console.log("Box1이 렌더링되었습니다.");
const onInitButtonClickHandler = () => {
initCount();
};
return (
<div style={boxStyle}>
<button onClick={onInitButtonClickHandler}>초기화</button>
</div>
);
}
위의 코드는 카운터를 증가 혹은 감소 혹은 초기화 시키는 코드이다.
여기서 중요하게 봐야 될 것은 바로 버튼을 눌렀을 때, App의 컴포넌트와 Box1의 컴포넌트 모두가 리렌더링이 된다는 것이다.
그 이유는 간단하다. 함수형 컴포넌트를 사용하기 때문에 리랜더링 되면서 코드가 다시 만들어지기 때문이다. 결과적으로 자바스크립트에서 함수도 객체의 한 종류이다. 따라서 모양은 같더라도 다시 만들어지면 그 주솟값이 달라지고 또한 하위 컴포넌트인 Box1은 pops가 변경되었다고 인식하게 된다.
그럼 어떻게 하면 될까?
// 변경 전
const initCount = () => {
setCount(0);
};
// 변경 후
const initCount = useCallback(() => {
setCount(0);
}, []);
이렇게 사용하면 된다. 이렇게 할 경우, App 컴포넌트만 리랜더링이 되는 것을 볼 수 있다.
더 나아가, 만약 count가 7일때 초기화 버튼을 누르면 콘솔에는 7에서 0으로 바뀌었습니다 라고
떠야된다. 하지만 0에서 0으로 변경되었다고 뜰 것이다. 그 이유는 위에서도 말했지만 useCallback은 초기값을 기억한다. 즉 초기 값 이었던 0을 기억하게 된다.
그럴 경우에 밑에와 같이 하면 된다.
// count를 초기화해주는 함수
const initCount = useCallback(() => {
console.log(`[COUNT 변경] ${count}에서 0으로 변경되었습니다.`);
setCount(0);
}, [count]);
의존성 배열에 state의 값을 넣어두면 콘솔에 잘 찍힐 것이다.
하루하루 리액트 hook에 대한 지식이 쌓여간다...