지난 번 useMemo와 함께 Memoization 기법을 활용해 컴퍼넌트를 최적화시켜주는 훅이다.
useMemo의 경우 값을 Memoization하여 재사용할 수 있다면 useCallback은 함수를 재사용할 수 있게 해준다.
const plusone = (num) => {
return num + 1;
};
const plusone = useCallback((num)=>{
return num + 1;
}, [item])
위 코드와 같이 plusone을 useCallback으로 함수를 감싸서 사용하면 된다.
useCallback()은 2개의 인자를 받는다.
하나는 우리가 Memoization해야 할 콜백함수, 두번째는 의존성 배열이다. 즉, 의존성 배열의 값이 변경되지 않는 이상 다시 초기화되지 않는다.
...
const doSomething = () => {
// do something
return;
}
useEffect(()=>{
// any action
}, [doSomething]);
return(<div>
...
위와 같은 코드가 있다고 가정하자. 이 부분은 지난 번 useMemo에서도 나왔던 내용이다. doSomething의 경우, 함수 즉 객체를 담고 있기 때문에 화면이 재 렌더링되면 주소 값이 계속 변경되기 때문에 useEffect를 계속 호출하게 된다.
...
const doSomething = useCallback(() => {
// do something
return;
}, []);
useEffect(()=>{
// any action
}, [doSomething]);
return(<div>
...
위와 같이 수정하면 최초 호출 시 doSomething은 Memoization 된다.
이후 useEffect에서 아무리 재 렌더링되어도 doSomething에는 동일한 주소를 갖고 있으니 useEffect가 불리지 않게 된다.
useCallback은 서로 관계없는 state가 변경될 때 그로 인해 다른 state가 함께 영향을 받아 그로 인해 퍼포먼스가 저하되는 상황을 막고 싶을 때 사용할 수 있다.
function App() {
const [size, setSize] = useState(100);
const createBoxStyle = () => {
return {
background: 'pink',
width: `${size}px`,
height: `${size}px`,
};
};
return (
<div>
<input type="number" value={size} onChange={ (e)=>setSize(e.target.value) } />
<Box createBoxStyle={createBoxStyle} />
</div>
);
}
const Box = ({ createBoxStyle }) => {
const [style, setStyle] = useState({});
useEffect(()=>{
console.log('Called useEffect');
setStyle(createBoxStyle());
}, [createBoxStyle]);
return <div style={style}></div>;
};
위와 같은 코드가 있다고 가정하자.
Box 컴퍼넌트의 useEffect는 최초 Box가 그려질때와 prop으로 전달 받는 createBoxStyle이 변경될때 호출된다.
여기에 만약 아래와 같이 새로운 state가 추가된다고 가정하자.
const [isDark, setIsDart] = useState(false);
버튼을 누를 때 마다 isDark에 따라 테마를 변경할 때 사용된다. (코드 생략)
그런데 버튼을 눌러 setIsDark가 호출되면 내가 원하지 않는 Box 내부의 useEffect가 호출되게 된다.
그 이유는 상술한 것처럼 createBoxStyle 객체가 변경되기 때문이다.
따라서 createBoxStyle에 useCallback을 적용해준다.
const createBoxStyle = useCallback(()=>{
return {
backgroundColor: 'pink',
width: `${size}px`,
height: `${size}px`,
}
}, [size]); // size를 의존성 배열로 적용한다.
이렇게하면 createBoxStyle 값이 Memoization된 값을 사용하기 때문에 Box 컴퍼넌트의 useEffect을 호출하지 않기 때문이다.
'Personal Posting > ReactJS' 카테고리의 다른 글
React Hook 정리 - 컴퍼넌트 최적화 (React.Memo) (0) | 2023.12.05 |
---|---|
React Hook 정리 - useReducer (0) | 2023.11.06 |
React Hook 정리 - useMemo (0) | 2023.10.13 |
React Hook 정리 - useContext (0) | 2023.07.01 |
React Hook 정리 - useRef (0) | 2023.06.30 |