useCallback을 이용한 useAsync 커스텀 훅 이해하기

지수님·2024년 2월 20일
post-thumbnail

리액트 hook은 정말 다양하군..

팀 프로젝트 진행 중 fetch 관련된 로딩 ui를 사용할 때가 많아서
재사용 가능 하게끔 함수를 추상화 시켜야했는데 어떻게 해야할지 고민이었다

구글링 해보니 사이트를 만들 때 fetch 관련된 로딩ui를 띄울 때 많이 쓰이는 방법이
useAsync 훅을 제작해 로딩이 필요한 부분에 가져다 쓰는 것이었다

사실 useAsync 로직은 이미 잘 만들어진 예제가 많았지만 그래도 내부 기능을 알고
사용하고 싶었다. 내부 기능을 알아야 해당 함수로 커스텀을 해 다른 기능에 사용 할 수도 있고
useAsync함수를 수월하게 적용하고 적용 후 에러가 나도 빠른 디버깅이 가능하기 때문이다

문제는 useAsync 예제를 찾아보니 대부분 리액트 기본 훅인 useCallback을 사용해서 커스텀 훅을 만들던데 나는 useCallback함수를 써본적이 없었다…ㅎㅎ

useCallback 공부하기

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

문서에서는 메모제이션 된 콜백을 반환합니다 라고 써있는데 메모이제이션이 뭐지..?

메모이제이션

함수나 컴포넌트의 결과를 저장하여 불필요한 리 렌더링을 방지하고 최적화를 위해 사용되는 기법
⇒ useCallback은 콜백함수를 저장해 불필요한 리 랜더링을 방지하는데 쓰이는 함수!

useCallback의 두가지 인자

  1. 메모이제이션 하고자 하는 콜백함수
  2. 의존성 배열(콜백함수가 의존하는 값)

콜백함수와 의존성 배열의 관계

의존성 배열 중 하나의 요소만 변화가 생겨도 메모이제이션 된 함수를 새로 생성하여 리 렌더링 된다 의존성 배열이 빈 배열일 경우 콜백함수가 최초 한번만 생성되고,
(= 콜백함수가 처음 생성되고 실행 될 때 한번만 리 랜더링 되고)
계속 같은 함수가 사용되어 콜백함수로 인한 리 렌더링이 아예 되지 않는다

useAsync 예제 이해하기

function useAsync(asyncFunction) {
	const [Loading, setLoading] = useState(false);
	const [error, setError] = useState(null);

	const wrappedFunction = useCallback(
		async (...args) => {
			setLoading(true);
			setError(null);
			try {
				return await asyncFunction(...args);
			} catch (error) {
				setError(error);
			} finally {
				setLoading(false);
			}
		},
		[asyncFunction],
	);

	return [Loading, error, wrappedFunction];
}

export default useAsync;

useCallback을 사용하여 의존성 배열에 asyncFunction을 넣어주었기 때문에,
asyncFunction이 실행될 때마다 매번 새로운 메모이제이션된 콜백 함수가 생성

⇒ useAsync를 사용하는 곳에서 wrappedFunction을 호출할 때마다
asyncFunction이 실행되면서 로딩 상태 갱신, 해당 상태를 토대로 로딩 UI를 표시 가능

나는 정말 리액트의 한정적인 훅만 사용했구나 라는걸 또 느꼈다(feat. useState, useEffect...)

React Forget

그런데 useCallback을 너무 늦게 알아버린 것일까..?
멘토님이 바로는 아니지만 React Forget 나와서 useCallback를 안쓸 수도 있으니 한번 알아보라고 말씀해 주셨다..! 사실 나는 있는 것도 배우고 코드에 적용해 보는데 시간이 오래 걸려서 요즘 개발 트렌드나 소식 같은 걸 따로 찾아볼 생각은 못했는데 여러 업데이트 소식에
관심을 가져보기 위해 다음 포스팅은 React Forget에 관한 내용을 알아봐야겠다!

profile
되어보자 개발자!

0개의 댓글