본문 바로가기

Personal Posting/ReactJS

React Hook 정리 - useCallback

 

지난 번 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